背包问题
1. 0-1背包
我们先从经典的0-1背包谈起,显然这是一个动态规划。这个过程”商量“的问题是遇到一个物品到底放还是不放呢?(每种物品仅有一件,可以选择放或不放。)它的商量方程就是:
m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i])————其中m[i][j]表示还有i个物品供选择,背包容量为j。
AC代码:
二维dp:
for(i=1;i<=n;++i) //i表示物品i;
{
for(j=0;j<=c;++j)//j表示背包容量;
{
if(j<w[i])
dp[i][j]=dp[i-1][j];
else
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
}
//这本质上就是一个由上到下,由左到右的填表过程;
一维dp:
for(i = 0;i<n;i++)
{
for(j = v;j>=w[i];j--)//01背包
{
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
//dp[j]表示j容量下背包的最大价值;
}
}
2. 完全背包
要先知道完全背包和01背包的区别,01背包n个物品,每一个物品有1个,而完全背包每一件物品有无数个,只要求求出在不大于W的情况下求出最大的值;(也就是说它可以继续选择同一件物品,不一定要换成别的物品)
故它的商量方程和01背包的只有一点点差别,就是是继续选该物品还是选下一件。
代码:
二维dp:
for(i=1;i<=n;++i)
{
for(j=0;j<=W;++j)
{
if(j<w[i])
dp[i][j]=dp[i-1][j];
else
dp[i][j]=get_max(dp[i-1][j],dp[i][j-w[i]]+p[i]);
}
}
一维dp:
for(i=1;i<=n;++i)
{
for(j=w[i];j<=W;++j)
dp[j]=max(dp[j],dp[j-w[i]]+p[i]);
}
背包问题还有各种变式,需要大家仔细琢磨。这里就不一一讲述了。