题目给出n个物品,物品的价值vi,质量为wi,现在要求出承重为w袋子能装下多少价值的物品,求出总价值;
考虑对于每个物品都有装和不装两个选择,称之为0-1背包问题;
用 dp[i][j] d p [ i ] [ j ] 来表示,只用第1-i个物品,承重不超过j的情况下,能获得的最大价值;
可以获得递推关系:
利用这一递推关系,遍历得出dp数组:
for(i from 1 to n)
for(j from 1 to w)
if(j<weight[i]) dp[i][j]=dp[i-1][j]
else dp[i][j]=max( dp[i-1][j] , dp[i-1][j-weight[i]]+value[i] )
最后
dp[n][w]
d
p
[
n
]
[
w
]
就是所求的,在n个物品,承重w的袋子里装下的物品的最大价值;
全部代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=106;
const int maxw=1e4+6;
const int INF=0x7fffffff;
class node{
public:
int value,weight;
node(int value=0,int weight=0):value(value),weight(weight){}
}a[maxn];
int n,w;
int dp[maxn][maxw];
int main() {
std::ios::sync_with_stdio(false);
cin>>n>>w;
int x,y;
for(int i=1;i<=n;i++){
cin>>x>>y;
a[i]=node(x,y);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=w;j++){
if(j<a[i].weight) dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i].weight]+a[i].value);
}
}
cout<<dp[n][w]<<endl;
return 0;
}
错点:
1. 遍历的时候,不可以直接
dp[i][j]=max(dp[i−1][j],dp[i−1][j−weight[i]]+value[i])
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
−
1
]
[
j
−
w
e
i
g
h
t
[
i
]
]
+
v
a
l
u
e
[
i
]
)
因为 当第i个不选择的时候,还有可能选择前面其他的物品;不能for(int j=a[i].weight)开始;