动态规划、贪心算法、分治法

文章目录

在算法设计中,贪心算法(Greedy Algorithms)、动态规划与分治法(Divide and Conquer)并列,是最基础、最重要的算法设计思想。

贪心算法

动态规划

小偷背包示例

knapsack是背包的意思。

代码:

java 复制代码
public class Knapsack01 {

    /**
     * 0-1 背包问题求解
     * @param W 背包的总容量
     * @param w 每个物品的重量数组
     * @param v 每个物品的价值数组
     * @return 背包能装下的最大价值
     */
    public static int knapsack(int W, int[] w, int[] v) {
        int n = w.length; // 物品的总个数
        
        // 1. 定义状态数组:dp[i][j] 表示前 i 个物品在容量为 j 时的最大价值
        // 行数是 n+1(包含0个物品的情况),列数是 W+1(包含容量为0的情况)
        int[][] dp = new int[n + 1][W + 1];

        // 2. 遍历物品(相当于填表的行)
        // 从第 1 个物品开始,直到第 n 个物品
        for (int i = 1; i <= n; i++) {
            
            // 3. 遍历背包容量(相当于填表的列)
            // 从容量 0 一直遍历到最大容量 W
            for (int j = 0; j <= W; j++) {
                
                // 核心决策:小偷面对第 i 个物品时的二选一
                if (j < w[i - 1]) {
                    // 情况 A:当前背包容量 j 小于物品重量 w[i-1]
                    // 小偷装不下这个物品,只能放弃。
                    // 此时的最大价值等于【没有这个物品时】的最大价值
                    dp[i][j] = dp[i - 1][j]; 
                } else {
                    // 情况 B:当前背包容量 j 大于等于物品重量 w[i-1]
                    // 小偷可以装下,此时需要比较"装"与"不装"哪个更划算
                    int notTake = dp[i - 1][j]; // 不装:继承上一行的结果
                    int take = dp[i - 1][j - w[i - 1]] + v[i - 1]; // 装:当前物品价值 + 剩余空间的最优解
                    
                    // 取两者中的最大值
                    dp[i][j] = Math.max(notTake, take); 
                }
            }
        }

        // 4. 返回最终结果:表格右下角的值,即前 n 个物品在容量 W 下的最大价值
        return dp[n][W];
    }

    // 测试代码
    public static void main(String[] args) {
        int W = 5; // 背包容量为 5
        int[] weights = {2, 3, 4}; // 物品重量
        int[] values = {3, 4, 5};  // 物品价值

        int maxValue = knapsack(W, weights, values);
        System.out.println("小偷能偷到的最大价值是: " + maxValue);
    }
}

代码与表格的对应关系

1、i对应表格的行(第几个物品)。注意数组下标从0开始,所以第i个物品的重量是wi-1。

2、j对应表格的列(当前的背包容量)。

3、dpij=Math.max(...)就是我们在表格里写下的那个"取最大值"的动作。

动态规划和贪心算法对比
对比维度 贪心算法 (Greedy) 动态规划 (DP)
核心思想 活在当下,只看眼前(局部最优) 统筹全局,步步为营(全局最优)
决策方式 做出选择后绝不后悔(无回溯) 会考察所有可能的子问题,择优保留
是否记笔记 不需要,只记录当前状态 必须记(通过表格/备忘录避免重复计算)
能否保证最优 不一定(取决于问题是否满足贪心性质) 一定能(只要状态转移正确)
运行效率 极高(通常只需排序或单次扫描) 相对较低(通常需要填表,遍历所有子问题)
空间消耗 极低(通常只需几个变量) 较高(需要额外的内存存储 DP 表格)
适用条件 贪心选择性质 + 最优子结构 重叠子问题 + 最优子结构 + 无后效性
通俗比喻 凭直觉走迷宫,选最顺眼的方向,绝不回头 走迷宫时记下每个路口的最优路线,稳扎稳打

分治法

分治法和归并排序经常划到一起。

分治法是核心思想,归并排序是其中一种具体的算法。

相关推荐
Zootopia6268 小时前
美国载人飞船Crew-13明晚发射!
人工智能·算法·机器学习·数学建模·无人机·创业创新·信息与通信
zhangfeng11339 小时前
qjlDim 含义 TurboQuant QJL Quantized Johnson-Lindenstrauss,量化JL随机投影
人工智能·算法·ai编程·npu
HwJack209 小时前
【HarmonyOS开发小实践】HarmonyOS GC 引用计数 vs 对象追踪,三种回收算法
jvm·算法·harmonyos
blxr_9 小时前
力扣hot100前k个高频元素https://leetcode.cn/problems/top-k-frequent-elements/
算法·leetcode·职场和发展
longlongzihan18 小时前
LeetCode 17电话号码的字母组合:回溯算法(DFS)详解
c++·算法·leetcode·深度优先
封印师请假去地球钓鱼18 小时前
边解边变的问题:从“决策依赖“一词出发
人工智能·算法
今晚打老虎19 小时前
c++之提高A(前缀和)(第三课)
数据结构·c++·算法
不会就选b20 小时前
算法日常・每日刷题--<贪心>26
数据结构·算法
hetao17338371 天前
2026-09-29 hetao1733837 的刷题记录
c++·算法
欣欣之王来了1 天前
AI合规专项:AI算法透明度的合规要求
人工智能·算法