[USACO10FEB]购买巧克力Chocolate Buying 【假背包真贪心】 By cellur925

题目传送门

继续dp刷题计划,看到这道题,第一眼感觉不就是显然的完全背包嘛。把背包打完要开始填充数组大小的时候成为了mengbier,发现数据极大,达到了1e18.显然这不是一道平凡的背包题目。

于是看了题解。wtf?这题是贪心???

emmm冷静分析:首先我们比较背包模型和这个模型,背包花费这一定的体积,那些价值一定会获得。而这个模型中,我们每花费一定的钱(体积),却只能满足一只奶牛。这是本题的关键。

那么就很难继续满足完全背包的性质了。

真想用背包?看到讨论里有人说如果这题写背包,那也得是多重背包,用二进制拆分物品。况且本题数据范围还这么大,1e18也拆不下。

所以还是老老实实贪心吧== 先把巧克力按价值从小到大排序,每次尽量选择小的巧克力价值。因为尽量选择了小的巧克力会给其他后面喜欢昂贵的奶牛留下希望。这就是很裸的贪心了。

感觉本题被打到普及/提高-的难度还是因为思维的惯性吧,看起来是背包就直接打了==

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 int n;
 8 ll ans,pur,B;
 9 struct Chocolate{
10     ll v,w;
11 }p[100090];
12 
13 bool cmp(Chocolate x,Chocolate y)
14 {
15     return x.v<y.v;
16 }
17 
18 int main()
19 {
20     scanf("%d%lld",&n,&B);
21     for(int i=1;i<=n;i++)
22         scanf("%lld%lld",&p[i].v,&p[i].w);
23     sort(p+1,p+1+n,cmp);
24     for(int i=1;i<=n;i++)
25     {
26 /*        if(pur+p[i].v>B) break;
27         //printf("%lld\n",pur); 
28         pur+=p[i].v*p[i].w;
29         ans+=p[i].w;
30         while(pur>B)
31             ans--,pur-=p[i].v;*/
32         if(B/p[i].v<p[i].w)
33         {
34             ans+=B/p[i].v;
35             break;
36         }
37         B-=p[i].v*p[i].w;
38         ans+=p[i].w;
39     }
40     printf("%lld",ans);
41     return 0;
42 }
View Code

猜你喜欢

转载自www.cnblogs.com/nopartyfoucaodong/p/9638874.html