题解 CF976E 【Well played!】

hicc0305

2019-02-14 16:33:20

Personal

题目意思,也就是说,如果你场上有n个怪,你有a张神圣之灵,b张心灵之火,那么请问,怎么能使场攻最大呢!哈哈哈天才!! 一开始以为这是一道DP题,结果比赛完爆0后,才知道原来是一道纯贪心 可以证明,把所有的翻倍都弄到一个身上,最后的结果是最大的。 剩下的使攻击力与血量相等的次数,全部分配到其他血量大于攻击力的精灵上即可。 但其实这道题有很多的小细节。比如要把翻倍放后面处理,不然就搞不清楚,究竟多少还剩~~多少张心灵之火~~多少次赋值生命值的次数了。 ``` #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define int long long using namespace std; struct node { int x,y; }q[200100]; int n,a,b,sum=0; bool cmp(node c,node d) {return c.x-c.y>d.x-d.y;} signed main() { // freopen("match.in","r",stdin); // freopen("match.out","w",stdout); scanf("%I64d%I64d%I64d",&n,&a,&b); for (int i=1;i<=n;i++) scanf("%I64d%I64d",&q[i].x,&q[i].y); sort(q+1,q+n+1,cmp);//先按差值进行排序后,处理好那些要被赋值 for(int i=1;i<=b;i++) sum+=max(q[i].x,q[i].y); for(int i=b+1;i<=n;i++) sum+=q[i].y; int ans=sum;//对每一个精灵枚举一遍翻倍,然后要被赋值的算增加值时,要减的是攻击力和生命值较大的那一个(因为前面加的时候是这么加的),不被赋值的直接减去攻击力就可以了。 for(int i=1;i<=b;i++) ans=max(ans,sum-max(q[i].x,q[i].y)+(q[i].x<<a)); sum=sum-max(q[b].x,q[b].y)+q[b].y; for(int i=b+1;i<=n && b;i++) ans=max(ans,sum-q[i].y+(q[i].x<<a)); printf("%I64d",ans); return 0; } ```