原题位置: https://www.luogu.org/problem/show?pid=2619
这道题是个贪心,怎么说是贪心呢,就是先选大的,后考虑小的;
千万不要把上句话的意思理解歪了,一开始我就理解歪了,然后华丽丽地TLE了;
其实就是for,然后如果当前这个值可以被选,就选到不能再选这个值为止;
还有一个小技巧,就是我们定义一个值,等于c,然后用这个值减,知道小于等于0,这样子比一直加到c好处理多了;
一开始我是加到c,太难处理了;
然后就是while和for就好了;
cpp
#include<iostream>
#include<cstdio>
#include<algorithm>
#define II int
#define B bool
#define R register
#define I 123456
using namespace std;
struct node {
II buy,nu;
}aa[I];
II n,c,ans;
B maP(node a1,node a2) { return a1.buy>a2.buy; }
int main()
{
freopen("1.in","r",stdin);
scanf("%d%d",&n,&c);
for(R II i=1;i<=n;i++)
{
scanf("%d%d",&aa[i].buy,&aa[i].nu);
}
sort(aa+1,aa+n+1,maP);
R II now=1, en=n;
while (aa[now].buy>=c) {
ans+=aa[now].nu;
now++;
}
while (1) {
R II ka=c;
// 小技巧;
for(R II i=now;i<=n;i++)
// 所谓的从大到小贪心就是这个枚举顺序了;
{
while (ka>=aa[i].buy&&aa[i].nu&&ka>0) {
ka-=aa[i].buy;
aa[i].nu--;
}
// 一直减到不能再减为止,然后换下一个值;
}
if(ka>0) for(R II i=n;i>=now;i--) {
if(aa[i].buy>=ka&&aa[i].nu) {
aa[i].nu--;
ka-=aa[i].buy;
break ;
}
}
// 找一个大于剩余值且最小的, 补全;
if(ka>0) break ;
// 如果还不行,证明剩下的组不成c了,结束;
ans++;
}
printf("%d\n",ans);
exit(0);
}
by pretend_fal
END;