动态规划结题总结

这篇博客总结了动态规划的几个关键部分,包括初始条件、边界条件和计算顺序。博主详细探讨了最长公共子串和最长公共子序列问题,提供了计算方法,包括时间复杂度为O(N^2)和O(NlogN)的解决方案。此外,还介绍了最长递增子序列问题,讲解了如何通过动态规划求解,并给出了具体的算法流程和实例解析。
摘要由CSDN通过智能技术生成

动态规划

       其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路

Demo:Coin  Change

 

 

 

 动态规划组成部分:

一、确定状态

最后一步:

 

 

 递归解法:


递归会重复遍历,递归层次会很高

采用动态规划:转态方程(二)

 动态规划组成部分三:初始条件和边界条件

动态规划组成部分:计算顺序

 

总结:

 

#include <iostream>
#include  <vector>
#include  <limits.h>

using namespace std;
//DP 适用于:计数、最值、存在性
//A={1,2,5} ==>coin value
//M         ==>coin numbers
int coinchange(vector<int> A,int M)
{
    vector<int>  f(M+1);
    int n=A.size();
    f[0]=0;
    int i,j;
    for(i=1;i<=M;i++){
        f[i]=INT_MAX;
        for(int j=0;j<n;j++){
            if(i>=A[j]&&f[i-A[j]]!=INT_MAX){
                f[i]=min(f[i-A[j]]+1,f[i]);
            }
        }
    }
   //超过最大值,说明没有找到啊
    if(f[M]==INT_MAX){
        return -1;
    }
    return f[M];
}

int main()
{
    vector<int>  A={1,2,5};
    int res=coinchange(A,11);
    cout<<res;
    return 0;
}

 例子2:机器人动态规划(unique paths):

1.确定状态

 

子问题

 DP维数:有几个变量,就开几维。

动态规划组成部分三:初始条件和边界条件

最后就是计算顺序:

 

code:

#include <iostream>
#include  <vector>
#define INT_MAX 100000

using namespace std;
//A={1,2,5} ==>coin value
//M         ==>coin numbers
//int coinchange(vector<int> A,int M)
//{
//    vector<int>  f(M+1);
//    int n=A.size();
//    f[0]=0;
//    int i,j;
//    for(i=1;i<=M;i++){
//        f[i]=INT_MAX;
//        for(int j=0;j<n;j++){
//            if(i>=A[j]&&f[i-A[j]]!=INT_MAX){
//                f[i]=min(f[i-A[j]]+1,f[i]);
//            }
//        }
//    }
//    if(f[M]==INT_MAX){
//        return -1;
//    }
//    return f[M];
//}
int uniquePaths(int m,int n)
{
 //M*N  ==two diamon
//  vector<vector<int> >  dp(m,vector<int>(n));
//  for(int i=0;i<m;i++){
//      dp[i].resize(n);
//  }
  int dp[m][n];
  int i,j;
  for( i=0;i<m;i++){
      for( j=0;i<n;j++){
      //初始化
          if(i==0||j==0){ //当i=0一行或者j=0一列,就只能有一种方法到达指定地方
              dp[i][j]=1;
          }else{
              dp[i][j]=dp[i-1][j]+dp
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值