无尽算法之 一个简单小示例 掌握动态规划算法!

题目: 在一个数组arr中,找出一组不相邻的数字,使得最后的和最大。

思路:

还是老套路, 每个数字都有两种可能, 选和不选, 递归搞定.
但是, 我们会发现递归的时候时间复杂度是呈指数上升的(log2^2),
我们会发现, 很多的子问题, 在普通递归中是被重复计算的, 所以我们需要将每一步的计算结果保存起来, 这样在上层方法利用到下层方法的计算结果时, 可以直接去拿而不需要重复计算, 我们一般使用迭代来实现动态规划算法.
什么是动态规划算法?

题解:

public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 4, 1, 7, 8, 3};
        System.out.println(recur_opt(arr.length - 1, arr));
        System.out.println(dp_opt(arr));
    }
普通解法:
// 普通迭代
    private static int recur_opt(int i, int[] arr) {
        if (i == 0) return arr[0];
        if (i == 1) return Math.max(arr[0], arr[1]);
        
        // 选i?
        int a = recur_opt(i - 2, arr) + arr[i];
        
        // 不选i?
        int b = recur_opt(i - 1, arr);
       
        return Math.max(a, b);
    }
动态规划算法
// 动态规划
    private static int dp_opt(int[] arr) {
    	
    	// 特殊退出条件
        if (arr.length == 1) return arr[0];  
        if (arr.length == 2) return Math.max(arr[0], arr[1]);
        
        // 保留中间计算结果, 降低复杂度
        int[] opt = new int[arr.length];
        opt[0] = arr[0];
        opt[1] = arr[1];
        
        for (int i = 2; i < opt.length; i++) {
            int a = opt[i - 2] + arr[i];
            int b = opt[i - 1];
            opt[i] = Math.max(a, b);
        }
       
        return opt[opt.length-1];
    }
}
发布了188 篇原创文章 · 获赞 323 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_33709508/article/details/104105980