【学习笔记】CF3B Lorry 题解
作者:互联网
题目传送门
正解
思路
-
因为物品的重量只有 1 和 2,所以考虑暴力枚举选择多少个 2 ,剩下的尽可能多地填充 1 即可。
-
为什么“尽可能多”正确呢?很显然,这是因为物品的价值 \(\ge 1\) 。
-
至于怎么选择,只需要将物品的价值从大到小排序,然后取靠前的即可。
-
注意使用前缀和优化。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll n,v;
struct num{
ll nu,po;
}j[100233],o[100233];
ll cj,co,qj,qo,t,w,ans=-1919810,rere=-1919810;
inline bool cmp(num a,num b){
return ((a.nu>b.nu)?true:((a.nu==b.nu)?a.po<=b.po:false));
}
int main(){
scanf("%lld%lld",&n,&v);
for(int i=1;i<=n;++i){
scanf("%lld%lld",&t,&w);
if(t==1){j[++cj].nu=w;j[cj].po=i;}
else{o[++co].nu=w;o[co].po=i;}
}
sort(j+1,j+cj+1,cmp);
sort(o+1,o+co+1,cmp);
ll fff=max(cj,co);
for(int i=1;i<=fff;++i){
j[i].nu+=j[i-1].nu;
o[i].nu+=o[i-1].nu;
}
for(int i=0;i<=co;++i){
if((i<<1)>v) break;
ll ott=min(v-(i<<1),cj);
rere=o[i].nu+j[ott].nu;
if(rere>ans){ans=rere;qj=ott;qo=i;}
}
printf("%lld\n",ans);
for(int i=1;i<=qj;++i)
printf("%lld ",j[i].po);
for(int i=1;i<=qo;++i)
printf("%lld ",o[i].po);
return 0;
}
/*
8 1919810
1 133
1 23333
1 33333
1 4333
1 5333
1 6333
1 222
1 998244353
*/
标签:1919810,题解,ll,nu,num,ans,include,CF3B,Lorry 来源: https://www.cnblogs.com/Konjac-Binaries/p/15441300.html