算法--动态规划(dp)

  • 动态规划(dynamic progromming)
  • 将一个复杂的问题分解成若干个子问题,通过综合子问题的最优解来得到原问题的最优解
  • 动态规划会将每个求解过的子问题的解记录下来,这样下一次碰到同样的子问题时,就可以直接使用之前记录的结果,而不是重复计算
  • 可以用递归或者递推的写法实现,递归的写法又叫记忆化搜索
  • 重叠子问题:如果一个问题可以被分解成若干个子问题,且这些子问题会重复出现,就称这个问题拥有重叠子问题。 一个问题必须拥有重叠子问题,才能用动态规划去解决。
  • 最优子结构:如果一个问题的最优解可以由其子问题的最优解有效地构造出来,那么称为这个问题拥有的最优子结构。最优子结构保证了动态规划中的原问题的最优解可以由子问题的最优解推导而来
  • 动态规划与分治的区别:都是分解为子问题然后合并子问题得到解,但是分治分解出的子问题是不重叠的
  • 动态规划与贪心的区别:都有最优子结构,但是贪心直接选择一个子问题去求解,会抛弃一些子问题,这种选择的正确性需要用归纳法证明,而动态规划会考虑所有的子问题
  • ---------------------------------以上转载柳神blog------------------------------------
  • 我个人的理解就是自底到上  从一个状态到另一个状态
  •   来看例题http://poj.org/problem?id=1163
  • 很典型的dp例题(既可以用dp也可以使用dfs)
  • #include<iostream>
    using namespace std;
    int main()
    {
        const int inf=105;
        int n,dp[inf][inf],a[inf][inf];
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=i;j++)
            cin>>a[i][j];
        }
        for(int i=1;i<=n;i++)
            dp[n][i]=a[n][i];
        for(int i=n-1;i>=1;i--)
          for(int j=1;j<=i;j++)
          {
                dp[i][j]=max(a[i][j]+dp[i+1][j],a[i][j]+dp[i+1][j+1]);
          }
          cout<<dp[1][1];
          return 0;
    }
如果你够坚强够勇敢,你就能驾驭他们
原文地址:https://www.cnblogs.com/liuzhaojun/p/11184448.html