题目描述
有 n 件物品, 每件物品有一个价值和一个重量,分别记为: b1,b2, …bn w1,w2, …wn 其中所有的 重量wi 均为整数。 现有一个背包,其最大载重量为W,要求从这n件物品中任取若干件(这些物品要么被装入要么被留下)。问背包中装入哪些物品可使得所装物品的价值和最大?
输入
第1行:2个整数n(1<=n<=1000)和W(1<=W<=10000),分别表示物品的件数和背包的最大载重量。
第2-n+1行:每行2个用空格分开的整数,第i+1行的整数表示第i件物品的重量wi和价值bi(1<=bi,wi<=10000)。
输出
第1行:1个整数,表示背包所能装下的物品的最大总价值。
第2-?行:每行3个用空格分开的整数,i, wi, bi,分别表示最优解中的物品的编号、重量和价值。
样例输入
4 5
2 3
3 4
4 5
5 6
样例输出
7
1 2 3
2 3 4
分析
这是个很普通的动规题,思路就不说了。
设 d(i,x)表示前i件物品,总重量不超过x的最优价值
则 d(i,x)=max(d(i-1,x-W[i])+C[i],d(i-1,x) );
d(n,m)即为最优解
边界条件为d(0,x)=0 ,d(i,0)=0;
但重要的是这个方案的输出,但这个方案的输出也不是特别的难,利用d数组顺推回去就好了。
完整代码
#include<cstdio>
#include<algorithm>
#define MAXN 1005
using namespace std;
int a[MAXN],b[MAXN],d[MAXN][MAXN*10];
void print(int w,int n)
{
if(n<=0)
return ;
if(w>=a[n]&&d[n][w]==d[n-1][w-a[n]]+b[n])
{
print(w-a[n],n-1);
printf("%d %d %d\n",n,a[n],b[n]);
}
else
print(w, n-1);
}
int main()
{
int i,j,n,w;
scanf("%d%d",&n,&w);
for(i=1;i<=n;i++)
scanf("%d%d",&a[i],&b[i]);
for(i=1;i<=n;i++)
for(j=1;j<=w;j++)
{
if(j>=a[i])
d[i][j]=max(d[i-1][j-a[i]]+b[i],d[i-1][j]);
else
d[i][j]=d[i-1][j];
}
printf("%d\n",d[n][w]);
print(w,n);
}