第八周总结(背包dp)
由于背包太多并未能完全掌握,主要为01背包的典型解题思路。(dp常常按照动态规划的思路来写)。
案例一(参照oj2.2第三题)
给出物品的质量和价值,求出背包能装下的最大价格。
用v[i]表示物品价值,w[i]表示物品重量,要使得放入背包的物品价值最大化。
思路:
dp[i][j] 以 jj 为容量为放入前i个物品(按 ii 从小到大的顺序)的最大价值。
核心 dp[i][j] = max(dp[i-1][j-w[i]])+v[i],dp[i-1][j])dp[i][j]=max(dp[i−1][j−w[i]])+v[i],dp[i−1][j])。
如果用二维数组(核心代码):
for(int i=1;i<=m;i++)
for(int j=t;j>=0;j--)
{
if(j>=w[i])
{
dp[i][j]=max(dp[i-1][j-w[i]]+val[i],dp[i-1][j]);
}
else
{
dp[i][j]=dp[i-1][j];
}
}
如果用一维数组:
for(int i=1;i<=m;i++)
{
for(int j=t;j>=0;j--)
{
if(j>=w[i])
{
dp[j]=max(dp[j-w[i]]+val[i], dp[j]);
}
}
}
案例二(oj2.3第一题)
这种题dp的是查找参数的状态,查当前的长度下能否满足条件
如果当前的字符串从后往前截了有一段集合中的串且截去这段串后的字串是合法的话那么当前串也是合法的
关键代码:
for (i=1;i<n.size();i++){//枚举子串
for (int j=min(i,m);j>=1;j--){
string tt=n.substr(i-j+1,j);//截除子串
if (s[tt.size()].count(tt)1&&dp[i-j]1){//如果合法
ans=i;//必定是最大的
dp[i]=1;//本身也合法
break;//没必要搜下去了
}
}
}
01背包的重点:内重循环应该要倒着扫!!!

浙公网安备 33010602011771号