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