1.最长回文字串。
用二维数组更新状态。table[i][j]表示第i个字符到第j个字符的字串是否为回文字串。
初始化为false,table[i][i]为true,一开始检查相邻的两个字符是否相等。
从长度为3开始自底向上递推,递推式为:
if(table[i+1][j-1]==true && table[i]==table[j])
table[i][j]==true;
2.最大子数组和
用两个变量更新状态:subsum:判断当前的b[i]加入到子数组的值。sum:最大子数组和。
subsum=max(b[i],subsum+b[i]). //如果当subsum<0时,那么就舍弃前面的和,重新以b[i]开始计和。
sum=max(sum,subsum). //比较当前子数组和和最大子数组和的大小。
3.切割成回文数
两次递归
一是p[i][j]判断从i到j是否为回文
二是f[i]=min{f[i],f[j]+1] (i<=i<n) 表示从i到n的子串需要最少切割几次。
4.最长公共子序列
5.最长子串
6.最长递增子序列
解法一:最长公共子序列法:
仔细思考上面的问题,其实可以把上面的问题转化为求最长公共子序列的问题。原数组为A{5, 6, 7, 1, 2, 8},下一步,我们对这个数组进行排序,排序后的数组为A‘{1, 2, 5, 6, 7, 8}。我们有了这样的两个数组后,如果想求数组A的最长递增子序列,其实就是求数组A与它的排序数组A‘的最长公共子序列。我来思考下原问题的几个要素:最长、递增、子序列(即顺序不变)。
递增:A‘数组为排序数组,本身就是递增的,保证了两序列的最长公共子序列的递增特性。
子序列:由于A数组就是原数组,其任意的子序列都是顺序不变的,这样就保证了两序列的最长公共子序列的顺序不变。
最长:显而易见。
解法二:动态规划法(O(N^2))
既然是动态规划法,那么最重要的自然就是寻找子问题,对于这个问题,我们找到他的子问题:
对于长度为N的数组A[N] = {a0, a1, a2, …, an-1},假设假设我们想求以aj结尾的最大递增子序列长度,设为L[j],那么L[j] = max(L[i]) + 1, where i < j && a[i] < a[j], 也就是i的范围是0到j – 1。这样,想求aj结尾的最大递增子序列的长度,我们就需要遍历j之前的所有位置i(0到j-1),找出a[i] < a[j],计算这些i中,能产生最大L[i]的i,之后就可以求出L[j]。之后我对每一个A[N]中的元素都计算以他们各自结尾的最大递增子序列的长度,这些长度的最大值,就是我们要求的问题——数组A的最大递增子序列。
时间复杂度:由于每一次都要与之前的所有i做比较,这样时间复杂度为O(N^2)
7.背包问题
-
for(int i = 1; i <= n; i++)
-
{
-
for(int j = 0; j <= W; j++)
-
{
-
if(j < w[i]) dp[i][j] = dp[i-1][j];
-
else dp[i][j] = max(dp[i-1][j], dp[i-1][j – w[i]] + v[i]);
-
}
今天的文章动态规划经典题目分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/5574.html