01背包
Description
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
Input
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
0 < N,V ≤ 1000
0 < vi,wi ≤ 1000
Output
输出一个整数,表示最大价值。
Sample Input
4 5 1 2 2 4 3 4 4 5
解答
解决背包问题显然不能穷举,时间复杂度O(2^n)肯定会爆
那我们就要用动态规划
转移方程不难分析,无非买与不买就是:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+p[i])
dp[i][j]代表前i个物品,当容量为j时,能够取得的最大价值
粘个代码
#include<cstdio>
int vi[1002],wi[1002],dp[1002][1002];
int max(int x,int y){
return x>y?x:y;
}
int main(){
int n,v;
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++){
scanf("%d%d",&vi[i],&wi[i]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=v;j++){
dp[i][j]=dp[i-1][j];
if(vi[i]<=j)
dp[i][j]=max(dp[i-1][j],dp[i-1][j-vi[i]]+wi[i]);
}
}
printf("%d",dp[n][v]);
}
完全背包
Description
有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。
第 i 种物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
0 < N,V ≤ 1000
0 < vi,wi ≤ 1000
Input
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。
Output
输出一个整数,表示最大价值。
Sample Input
4 5 1 2 2 4 3 4 4 5
Sample Output
10
解答
只需要把转移方程改一下就好了
dp[i][j]=max(dp[i-1][j],dp[i][j-v[i]]+p[i])
这样就能实现累加
#include<cstdio>
int vi[1002],wi[1002],dp[1002][1002];
int max(int x,int y){
return x>y?x:y;
}
int main(){
int n,v;
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++){
scanf("%d%d",&vi[i],&wi[i]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=v;j++){
dp[i][j]=dp[i-1][j];
if(vi[i]<=j)
dp[i][j]=max(dp[i-1][j],dp[i][j-vi[i]]+wi[i]);
}
}
printf("%d",dp[n][v]);
}