简单的背包问题

来源:互联网 发布:仿美文网整站源码 编辑:程序博客网 时间:2024/06/03 00:48

题目连链接:
1279: 简单的背包问题
时间限制: 1 秒 内存限制: 32 MB
提交: 411 解决: 36
提交 状态
题目描述

相信大家都学过背包问题了吧,那么现在我就考大家一个问题。有n个物品,每个物品有它的重量w,价值v,现在有一个容量为W的背包,问你在不超过背包容量的情况下,能装下的物品的最大价值是多少。

T <= 100代表样例数
1 <= n <= 100 物品数
1 <= W <= 100000 背包的容量
1 <= wi <= 100000 每个物品的重量
对于每个i=2,3,…,N, w1 ≤ wi ≤ w1+3.
1 <= vi <= 100000 每个物品的价值
输入

输入格式:

T
n W
w1 v1
w2 v2
:
wn vn

输出

输出占一行,代表最大能装下物品的价值。
样例输入

2
4 6
2 1
3 4
4 10
3 4
4 6
2 1
3 7
4 10
3 6
样例输出

11
13
分析:一开始我看错了没有注意数据范围,一上去就把背包问题写了上去,一直wa了十几次,浪费了大量时间。赛后看题解才知道,重量有限制,只能在w1,w1+1,w1+2,w1+3,这四个范围之内。可以先给这个个分组,每一组按价值从大到小排,对于每组优先装入价值最大的。求个前缀和,四个for求最值就可以了,就是个贪心,被这个背包问题的题目迷惑了。
ac代码:

#include<cstdio>#include<cmath>#include<cstring>#include<iostream>#include<string>#include<algorithm>using namespace std;typedef long long  ll;int cmp(ll a,ll b){    return a>b;}int main(void){    int t;    cin>>t;    while(t--){        ll d[4][105];        ll n,W;        ll w1;        cin>>n>>W;        int a,b,c,d1;        a = b = c = d1 = 0;        cin>>w1>>d[0][++a];        for(int i=1;i<n;i++){            int xx,yy;            cin>>xx>>yy;            if(xx==w1){                d[0][++a] = yy;            }            else if(xx==w1+1){                d[1][++b] = yy;            }            else if(xx==w1+2){                d[2][++c] = yy;            }            else{                d[3][++d1] = yy;            }        }        sort(d[0]+1,d[0]+a+1,cmp);        sort(d[1]+1,d[1]+b+1,cmp);        sort(d[2]+1,d[2]+c+1,cmp);        sort(d[3]+1,d[3]+d1+1,cmp);        d[0][0] = d[1][0] =d[2][0] =d[3][0] = 0;        for(int i =2;i<=a;i++){            d[0][i]+=d[0][i-1];        }        for(int i=2;i<=b;i++){            d[1][i]+=d[1][i-1];        }        for(int i=2;i<=c;i++){            d[2][i]+=d[2][i-1];        }        for(int i=2;i<=d1;i++){            d[3][i]+=d[3][i-1];        }        ll res = 0;        for(int i=0;i<=a;i++){            for(int j=0;j<=b;j++){                for(int k=0;k<=c;k++){                    for(int l=0;l<=d1;l++){                        ll sum = w1*i+(w1+1)*j+(w1+2)*k+(w1+3)*l;                        if(sum<=W){                            res = max(res,d[0][i]+d[1][j]+d[2][k]+d[3][l]);                        }                    }                }            }        }        cout<<res<<endl;    }    return 0;}/**************************************************************    Problem: 1279    User: henuwhr    Language: C++    Result: 正确    Time:460 ms    Memory:1704 kb****************************************************************/
原创粉丝点击