BZOJ-1135 01背包问题

题目描述

有 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值