动态规划经典题目

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. }
  • 11
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值