动态规划经典题目

动态规划经典题目1.最长回文字串。  用二维数组更新状态。table[i][j]表示第i个字符到第j个字符的字串是否为回文字串。  初始化为false,table[i][i]为true,一开始检查相邻的两个字符是否相等。  从长度为3开始自底向上递推,递推式为:  if(table[i+1][j-1]==true&&table[i]==table[j])    table…

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.背包问题


  1. for(int i = 1; i <= n; i++)

  2. {

  3. for(int j = 0; j <= W; j++)

  4. {

  5.   if(j < w[i]) dp[i][j] = dp[i-1][j];

  6.   else dp[i][j] = max(dp[i-1][j], dp[i-1][j – w[i]] + v[i]);

  7. }

今天的文章动态规划经典题目分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/5574.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注