问题描述:
有N件物品和一个容积为M的背包。第i件物品的体积为volume[i],价值为worth[i]。求解将哪些物品装入背包可使价值总和最大。每种物品只有一件,可以选择放或者不放。(N<=3500,M<=13000)
输入格式:
第一行为物品数量N和背包容积M
每行依次输入第i件物品的价值和体积
样例输入:
3 10
3 4
2 6
6 7
样例输出:
6
提示:
采用滚动数组防止超出内存要求
代码如下:
#include<cmath>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int N,M; //N件物品,背包容积为M
cin>>N>>M; //输入物品数量,背包容积
int worth[N+1]; //worth[i]为第i件物品价值,下标从1开始
int volume[N+1]; //volume[i]为第i件物品体积 ,下标从1开始
int dp[M+1];
memset(dp,0,sizeof(dp));
int i,j;
for(i=1;i<=N;++i) //依次同时输入第i件物品的价值和体积
cin>>worth[i]>>volume[i];
for(i=1;i<=N;++i) //使用滚动数组 取前i件物品
{
for(j=M;j>0;--j) //请思考 总体积不超过j
{
if(i==1&&volume[1]<=j) //边界 取前1件物品
dp[j]=worth[1];
else //动态转移方程 选第i件物品或不选
{
int A=dp[j],B=0;
if(j>=volume[i])
B=dp[j-volume[i]]+worth[i];
dp[j]=max(A,B);
}
}
}
cout<<dp[M]<<endl;
return 0;
}
运行结果:
区分:
01背包问题:物品个数为1
多重背包问题:物品个数有限
完全背包问题:物品个数无限