第一步:先明确 “子问题” 和 “重复子问题” 的定义

在算法中,“子问题” 不是泛指 “小一点的问题”,而是具有明确 “状态参数” 的、可独立求解的问题单元

  • 状态参数:描述子问题核心信息的变量(比如 01 背包中的 “剩余物品范围” 和 “剩余背包容量”,斐波那契中的 “第 n 项”)。
  • 重复子问题:若两个子问题的 “所有状态参数完全相同”,则它们是重复子问题 —— 意味着这两个子问题的解完全一致,无需重复计算。

第二步:以 01 背包为例,拆解暴力递归的重复子问题

01 背包的暴力解法是 “递归枚举每个物品的‘选 / 不选’”,我们通过具体路径分析重复子问题的产生过程。

1. 01 背包的暴力递归逻辑回顾

暴力递归函数定义:dfs(i, c) = 考虑前i+1个物品(0~i)、剩余容量c时的最大价值。
对每个物品i,有两种选择:

  • 不选:递归调用dfs(i-1, c)
  • 选(若w[i] ≤ c):递归调用v[i] + dfs(i-1, c - w[i])

2. 暴力枚举的 “路径冗余” 导致重复子问题

假设我们有 3 个物品:w = [2,3,4],v = [3,4,5],背包容量C=7。我们分析 “计算dfs(2, 7)(前 3 个物品,容量 7)” 时的路径:

为了计算dfs(2,7),需要先计算两个子问题:

  • 不选物品 2(重量 4):需计算dfs(1,7)(前 2 个物品,容量 7);
  • 选物品 2(重量 4):需计算4 ≤7,因此需计算5 + dfs(1, 7-4)=5 + dfs(1,3)(前 2 个物品,容量 3)。

接下来计算dfs(1,7)(前 2 个物品,容量 7):
dfs(1,7)又依赖两个子问题:

  • 不选物品 1(重量 3):需计算dfs(0,7)(前 1 个物品,容量 7);
  • 选物品 1(重量 3):需计算4 + dfs(0, 7-3)=4 + dfs(0,4)(前 1 个物品,容量 4)。

再计算dfs(1,3)(前 2 个物品,容量 3):
dfs(1,3)也依赖两个子问题:

  • 不选物品 1(重量 3):需计算dfs(0,3)(前 1 个物品,容量 3);
  • 选物品 1(重量 3):需计算4 + dfs(0, 3-3)=4 + dfs(0,0)(前 1 个物品,容量 0)。

现在重点来了:
如果我们继续枚举其他路径(比如 “选物品 0、不选物品 1” 和 “不选物品 0、选物品 1”),会发现:

计算dfs(0,7)dfs(0,4)dfs(0,3)dfs(0,0)这些子问题时,它们的状态参数(i=0+ 不同c)会在多个不同的 “选 / 不选” 组合路径中反复出现。

比如dfs(0,3)(前 1 个物品,容量 3):

  • 路径 1:不选物品 2 → 不选物品 1 → 处理物品 0(此时状态是i=0, c=3);
  • 路径 2:选物品 2 → 不选物品 1 → 处理物品 0(此时状态也是i=0, c=3)。

这两条完全不同的路径,最终指向了同一个子问题(i=0, c=3),暴力解法会对这个子问题重复计算两次 —— 这就是重复子问题的根源。

第三步:再看斐波那契,理解 “指数级重复” 的本质

斐波那契的暴力递归(无记忆化)是 “重复子问题” 的极端案例,能更直观看到 “重复计算的爆炸式增长”。

1. 斐波那契的暴力递归逻辑

fib(n) = fib(n-1) + fib(n-2),终止条件fib(0)=0fib(1)=1

2. 递归树中的重复子问题

fib(5)为例,其递归树如下:

fib(5)
├─ fib(4)
│  ├─ fib(3)
│  │  ├─ fib(2)
│  │  │  ├─ fib(1)  # 重复计算
│  │  │  └─ fib(0)  # 重复计算
│  │  └─ fib(1)      # 重复计算
│  └─ fib(2)
│     ├─ fib(1)      # 重复计算
│     └─ fib(0)      # 重复计算
└─ fib(3)├─ fib(2)│  ├─ fib(1)      # 重复计算│  └─ fib(0)      # 重复计算└─ fib(1)          # 重复计算

可以看到:

  • fib(3)被计算了 2 次,fib(2)被计算了 3 次,fib(1)被计算了 5 次 —— 子问题的重复次数随n呈指数级增长。
  • 暴力解法没有记录这些子问题的解,每次遇到fib(k)都要重新递归到底,导致时间复杂度达到O(2^n)

第四步:总结暴力算法产生重复子问题的核心原因

暴力算法(尤其是递归枚举类)之所以会有重复子问题,本质是 **“枚举路径的冗余” 与 “子问题状态的共享” 之间的矛盾 **:

  1. 枚举路径的冗余:暴力解法为了覆盖 “所有可能的解”,会枚举大量不同的选择路径(比如 01 背包的 “选 / 不选” 组合、斐波那契的 “先算 n-1 还是 n-2”)。这些路径看似不同,但在 “逐步拆解为子问题” 的过程中,会不可避免地交汇到相同的状态。
  2. 子问题状态的共享:子问题的解只由 “状态参数” 决定(与到达该状态的路径无关)。比如 01 背包的dfs(i,c),无论通过 “选 A 不选 B” 还是 “不选 A 选 B” 到达,解都是相同的 —— 但暴力解法没有利用这种 “共享性”,而是对每条路径上的相同状态重复计算。

关键对比:为什么分治算法(如归并排序)没有重复子问题?

很多人会疑惑:“分治也拆分子问题,为什么没有重复子问题?”—— 这能帮我们进一步理解本质:
分治算法(如归并排序、快速排序)的子问题是 “不重叠、无共享” 的。比如归并排序将数组拆分为 “左半部分” 和 “右半部分”,左半部分的子问题和右半部分的子问题完全独立(状态参数无交集),不会出现 “同一个状态被两个不同子问题依赖” 的情况,因此无需处理重复子问题。

而暴力递归(如 01 背包、斐波那契)的子问题是 “重叠、共享” 的 —— 不同的父问题可能依赖同一个子问题,这才导致了重复计算。

最终结论

暴力算法的核心目标是 “枚举所有可能解”,但为了覆盖所有解,它会产生大量 “路径冗余”;而子问题的解只由 “状态参数” 决定(与路径无关),这就导致不同路径会反复遇到相同的子问题 —— 这就是暴力算法存在重复子问题的根本原因。

而动态规划(DP)的核心价值,正是通过 “记忆化” 或 “递推表” 记录这些重复子问题的解,让每个子问题只计算一次,从而将时间复杂度从暴力的 “指数级” 降到 “多项式级”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94548.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94548.shtml
英文地址,请注明出处:http://en.pswp.cn/web/94548.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络】添加路由时,via和dev参数作用、直连路由

文章目录概述1、带via1.1 添加路由前的初始状态1.2. 执行添加路由的命令1.3. 添加路由后的状态2、不带 via (使用设备接口),直连3、带via还是不带via ?4、dev xx的作用4.1 命令中带via时,建议不带 dev eth0 (让系统自动判断)4.2 命令中带via&#xff0c…

云原生---企业级Kubernetes

一、Kubernetes介绍 1.简介 kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能: 自我修复:一旦某一个容器…

无人机三维路径规划首选算法:RRT_

无人机三维路径规划首选算法:RRT* 要判断哪种算法更适合无人机三维路径规划,需先明确无人机三维路径规划的核心需求,再结合各算法的底层逻辑与特性进行匹配。以下先梳理核心需求,再逐一分析算法特性,最终通过对比得出结…

CentOS 7 服务器初始化:从 0 到 1 的安全高效配置指南

前言 对于运维或开发人员而言,新到手的 CentOS 7 服务器绝非 “开箱即用”—— 默认的国外软件源下载缓慢、系统缺乏基础工具、防火墙未做安全配置,这些问题都会影响后续使用效率与服务器安全性。本文整理了 CentOS 7 服务器初始化的全套实操方案&#…

32.Attention-注意力机制

不是所有的信息都是有用的,或者说重要的。我们应该把注意力放在他该在的地方。 在人工智能领域,注意力机制被广泛应用。他可以帮助模型关注与当前任务相关的特征,而忽略不重要的特征,以提高准确率。注意力机制本质:即通…

如何设计 “用户共创型” IP 成长社群模型?​

“用户共创型” IP 成长社群的核心,是从 “IP 单向输出” 转向 “IP 与用户共生”,让用户从 “被动接收者” 变为 “主动参与者”,通过 “需求共建、内容共造、价值共享” 形成闭环,既强化用户归属感,又为 IP 注入持续…

Windows 命令行:mkdir 命令

专栏导航 上一篇:Windows 命令行:dir 命令 回到目录 下一篇:MFC 第一章概述 本节前言 本节,我们来讲解一个常见的命令,mkdir 命令。 学习本节知识,需要你首先懂得如何打开一个命令行界面,…

Linux系统编程——进程(函数)

回调函数:atexit()原型: int atexit(void (*function)(void));功能: 注册进程退出前执行的函数参数: function 函数指针,指向void返回值void参数的函数指针返回值 成功 返回0失败 …

均胜电子上半年毛利率持续提升,汽车智能化与机器人业务多点突破

8月25日,全球领先的智能汽车科技解决方案提供商均胜电子(600699.SH)发布2025上半年业绩,报告期内公司实现营业收入约303.47亿元,同比增长12.07%;营业利润总额约12.47亿元,归母净利润同比增长11.…

【QT入门到晋级】进程间通信(IPC)-共享内存

前言 前面分享了几种IPC通信技术,都有成熟的交互机制(阻塞和非阻塞方式交互),而本文分享的共享内存,更像是系统提供了一张“白纸”,让多个进程自己构建管理及安全机制,而有些场景只需要简单的机…

自动化测试概念与 Web 自动化实战(基于 Selenium)

在软件测试领域,自动化测试是提升测试效率、保障回归测试质量的核心手段。尤其对于 C 开发的项目,自动化测试能有效减少重复手工操作,避免新增功能对历史功能的影响。本文从自动化基础概念入手,详解自动化分类、Web 自动化测试核心…

NeRAF、ImVid论文解读

目录 一、NeRAF 1、概述 2、方法 3、训练过程 4、实验 二、ImVid 1、概述 2、Imvid数据集 3、STG方法 一、NeRAF 1、概述 NeRF类方法仅支持视觉合成功能,缺乏声学建模能力。对于以往的声学建模(如NAR/INRAS)会忽略三维场景几何对声…

重复文件删除查找工具 Duplicate Files Search Link v10.7.0

软件介绍 Duplicate Same Files Searcher 是一款面向 Windows 平台的专业重复文件检索与清理工具,兼具符号链接替换与 NTFS 高级特性支持,可在无损数据的前提下大幅缩减磁盘冗余。 软件使用 软件打开后是英文版,手动切换中文(按…

简易shell

目录 一、整体功能概述 函数准备 1.env命令 2.getenv()函数 3.snprintf 4.strtok()函数 三、全局变量 四、核心功能函数解析 1. 信息获取函数 2. 命令行交互 3. 命令解析 4. 普通命令执行 5. 内置命令处理(核心功能) 五、主函数流程 六、总…

网关资源权限预加载:从冷启动阻塞到优雅上线的完整闭环

网关资源权限预加载:从冷启动阻塞到优雅上线的完整闭环 基于 Spring Cloud Gateway + Spring Cloud Alibaba Nacos ——一篇可落地的技术方案与源码级实现 1. 场景与痛点 在微服务网关层做 统一资源权限校验 时,必须满足: 启动阻塞:所有权限规则加载完成前,不监听端口,拒…

open webui源码分析8—管道

我们可以把Open WebUI想象成一个管道系统,数据通过管道和阀门流动。管道作为open webui的插件,可以为数据构建新的通路,可以自定义逻辑和处理数据;阀门是管道的可配置部件,控制数据流过管道时的行为。管道可以理解成用…

深入理解 C 语言 hsearch 哈希表:限制、技巧与替代方案

概述 C 语言标准库中的 hsearch 系列函数提供了一套简单易用的哈希表实现,包含在 <search.h> 头文件中。这组函数虽然接口简洁,但在实际使用中存在一些重要的限制和注意事项。本文将深入探讨 hsearch 的功能特点、设计局限,并提供实用的解决方案和替代建议。 hsearc…

Web网络开发 -- HTML和CSS基础

HTML 超文本编辑语言 HTML 介绍 HTML的英文全称是 Hyper Text Markup Language&#xff0c;即超文本标记语言。HTML是由WEB的发明者 Tim Berners-Lee &#xff08;蒂姆伯纳斯李&#xff09;和同事 Daniel W. Connolly于1990年创立的一种标记语言&#xff0c; 它是标准通用化标…

Python爬虫实战:研究开源的高性能代理池,构建电商数据采集和分析系统

1. 绪论 1.1 研究背景与意义 随着互联网技术的飞速发展,网络数据已成为信息时代的核心资源之一。从商业角度看,企业通过分析竞争对手的产品信息、用户评价等数据,可制定更精准的市场营销策略;从学术研究角度,研究者通过爬取社交媒体数据、学术文献等,可开展社会网络分析…

项目设计文档——爬虫项目(爬取天气预报)

一、项目背景以及项目意义 项目背景&#xff1a; 爬虫技术的核心目的是自动化地从互联网上采集&#xff0c;提取和存储数据。网络爬虫是一种自动化程序&#xff0c;用于从互联网上抓取数据并进行处理。C语言因其高效性和接近硬件的特性&#xff0c;常被用于开发高性能的网络爬…