动态规划经典题目

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


4.最长公共子序列


5.最长子串

动态规划经典题目_第1张图片


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. }

你可能感兴趣的:(动态规划经典题目)