简单的背包问题

题目连链接:
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
****************************************************************/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值