【暴力枚举】AtCoder - arc073_b Simple Knapsack

题目链接https://vjudge.net/contest/410631#problem/J

题意:给出n个物品和一个容量为W的包,随后n行给出每个物品的重量wi和价值vi,挑出价值小于等于W并且价值最大的物品,输出最大价值。

数据范围:n<=100,w<=1e9,v<=1e7,w1<=wi<=w1+3

思路:n的范围只有100,w的值只有四种,w1,w1+1,w1+2,w1+3,所以 n 3 n^3 n3枚举就可以,只要枚举w1,(w1+1),(w1+2)的个数,算出(w1+3)的个数,从大到小取就可以。

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define pb push_back
using namespace std;

typedef long long ll;
typedef pair<int,int>P;
typedef unsigned long long ull;
vector<int>G[5];
bool cmp(int a,int b){return a>b;}
int main(){
    int n,W;scanf("%d%d",&n,&W);
    int w1,x;scanf("%d%d",&w1,&x);
    G[0].pb(x);
    for(int i=1;i<n;i++)
    {
        int w,v;scanf("%d%d",&w,&v);
        G[w-w1].pb(v);
    }
    ll ans=0;
    for(int i=0;i<4;i++)sort(G[i].begin(),G[i].end(),cmp);
    for(int i=0;i<=(int)G[0].size();i++)
        for(int j=0;j<=(int)G[1].size();j++)
        for(int k=0;k<=(int)G[2].size();k++)
    {
        ll sum=1ll*i*w1+1ll*j*(w1+1)+1ll*k*(w1+2);
        if(sum>W)continue;
        int tmp=(W-sum)/(w1+3);
        ll res=0;
        for(int p=0;p<i;p++)res+=G[0][p];
        for(int p=0;p<j;p++)res+=G[1][p];
        for(int p=0;p<k;p++)res+=G[2][p];
        for(int p=0;p<min(tmp,(int)G[3].size());p++)res+=G[3][p];
        ans=max(ans,res);
    }
    printf("%lld\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值