继续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 ",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 }