Dev.C++动态规划01背包:背包是一种特殊动态规划,而01背包就是只有选与不选的状态,这是最简单的理解。
老规矩,先贴代码:
#include<bits/stdc++.h>
using namespace std;
int bag,n,v[101],w[101],dp[1001][1001];
int main()
{
scanf("%d%d",&bag,&n);
for(int i=1;i<=n;i++)scanf("%d%d",&v[i],&w[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=bag;j++)
{
if(j>v[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
else dp[i][j]=dp[i-1][j];
}
}
cout<<dp[n][bag]<<endl;
return 0;
}
变量解释:bag:背包总容量
- n:物品的数量
- v[i]:第i件物品的体积
- w[i]:第i件物品的价值
- dp[i][j]:第i件物品和在它以前选的j重量的情况下的最佳选择方案的总价值
解释代码:
//重点代码
for(int i=1;i<=n;i++)
{
for(int j=1;j<=bag;j++)
{
if(j>v[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
else dp[i][j]=dp[i-1][j];
}
}
第一层循环:枚举每一件物品
第二层循环:枚举每一种重量
条件语句:对是否放的下第i件物品的判断
状态转移方程:
dp[i-1][j]:不选这件物品的情况。为什么是这样呢?j不动,是指没有放入任何东西。这就是不选的情况。
dp[i-1][j-v[i]]+w[i]:选择这件物品的情况。为什么呢?j-v[i],是目前背包内剩余空间减去这件物品的体积,加w[i],是指加上这件物品的价值。
在这两种情况中取max,就是目前的最佳情况了。这就是二维数组动态规划01背包的做法。