动态规划

本文深入讲解动态规划的基本思想和框架,通过两个实例:求最长回文子串和求子数组的最大和,展示如何通过子问题的解逐步累积推导出原问题的解,实现高效算法设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态规划

动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解

动态规划框架

//动态规划框架
//初始化 base case
dp[0][0][...] = base
//进行状态转移
for '状态1' in '状态1的所有取值':
    for '状态2' in '状态2的所有取值':
        for ...
            dp[状态1][状态2][...] = 求最值(选择1,选择2...)

通俗的解释:通过子问题的解逐步累积推导出原问题的解。

实例1:求最长回文子串

//dp[j][i] 字符串从j->i是否为回文数
//动态回归方程d[i-1][j+i]是否为回文数
public String longestPalindrome(String s) {
    int len=s.length();
    boolean[][] dp = new boolean[len][len];
    int max=-1;
    String str="";
    for (int i = 0; i < len; i++) {
        for (int j = 0; j <= i; j++) {
            if (s.charAt(j) == s.charAt(i) && (i - j <= 2 || dp[j+1][i-1]))
                dp[j][i] = true;
            if(dp[j][i] && i-j>max) {
                max=i-j;
                str=s.substring(j,i+1);
            }

        }
    }
    return str;
}

实例2:输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)

/*
字串问题一般都是分解子问题的过程,假设数组长度只有1个,不用求就只能是这个一元素的大小了,如果是2个元素,3个元素呢

元素个数 最大和

1 		[0]
2 		max([0]+[1],[1])
3 		max([1]+[2],[2])
4 		max([2]+[3],[3])
...
...
n max([n-1]+[n],[n])

分析:
1.当[n]>=[n-1]+[n]的时候说明[n-1]对结果产生了副作用,以n-1结尾的钱n项和还不如n项大,那么n项就作为起点位置了
2.当[n]<[n-1]+[n]的时候说明[n-1]对结果产生了正面作用,继续判断下一部分
3.综合以上分析这明显就是动态规划的特征(核心思想是把原问题分解成子问题进行求解,也就是分治的思想)
4.综合起来dp[i] 作为以i结尾连续字串最大和,本质就只有三行代码
	max = dp[0] = nums[0];
	dp[i] = Math.max(dp[i - 1] + nums[i], nums[i])
	max = Math.max(max, dp[i]);
5. 当[n]>[n-1]+[n]时记录起始位置下标,当[n-1]+[n]>[n]时记录结束坐标,dp[i]>max时,则记录最大和
*/
 //java代码
 public int maxSubArray(int[] nums) {
        int len = nums.length;
        int[] dp = new int[len];
        dp[0] = nums[0];
        int max = dp[0];
        for (int i = 1; i < len; i++) {
            dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
            max = Math.max(max, dp[i]);
        }
        return max;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值