您的位置:首页 > 其它

经典动态规划的迭代条件

2017-08-13 22:16 211 查看
1、硬币找零:

if(j<penny[i])
dp[i][j] = dp[i-1][j];
else
dp[i][j] = dp[i-1][j]+dp[i][j-penny[i]];
//其中,i代表硬币种类,j代表目标钱数,dp[i][j]表示由i种硬币凑成钱数j的方法个数。


2、经典的LIS(即最长上升子序列)问题:

int temp=0;
for(int j=0;j<i;j++)
{
if(A[i]>A[j])
temp = temp>dp[j]?temp:dp[j];
}
dp[i] = temp+1;
//dp[i]表示最后一个字符为i的最长上升序列的长度。思路:找到i前面,比A[i]小的字符中最长上升序列的长度然后加1


3、两个字符串A、B的最长公共子序列的长度

int res = max(dp[i-1][j],dp[i][j-1]);
if(A[i] == B[j])
res = max(dp[i-1][j-1]+1,res);
dp[i][j] = res;
//dp[i][j]表示A[0-i]与B[0-j]的最长公共子序列的长度。


4、0-1背包问题

if(j>=w[i])
dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
else
dp[i][j] = dp[i-1][j];
//i表示i个物品,j表示背包承重,w[i]表示第i个物品重量,v[i]表示第i个物品价值。
//完全背包以及0-1背包的改进,可以参考http://blog.csdn.net/kangroger/article/details/38864689


5、对于两个字符串A和B,我们需要进行插入、删除和修改操作将A串变为B串,定义c0,c1,c2分别为三种操作的代价,请设计一个高效算法,求出将A串变为B串所需要的最少代价。

if(A[i-1] == B[j-1])
dp[i][j] = min(dp[i-1][j-1],min(dp[i][j-1]+c0,dp[i-1][j]+c1));
else
dp[i][j] = min(dp[i-1][j-1]+c2,min(dp[i][j-1]+c0,dp[i-1][j]+c1));


6、word break

for(int j=0;j<i;j++)
{
if(dp[j]&&dict.find(s.substr(j,i-j)) != dict.end())
{
dp[i] = true;
break;

4000
}
}
//思路:dp[i]表示以s[i-1]结尾的字符串能否被分割,需要从0-(i-1)遍历,查看dp[j]是否为true同时s[j-(i-1)]是否在dict中,若有一个满足则dp[i]为true并跳出循环。
//注意substr和substring的区别,substr(pos,n)表示从下标pos开始n个字符,substring(pos1,pos2)表示从下标pos1到下标pos2.


个人总结:

dp分为两种:一种是只与有限个状态有关,一般为二维dp,与dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]有关,如1、3、4、5。

另一种是与前i-1个状态都有关,一般为一维dp,如2、6。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息