Canada Cup 2016

来源:互联网 发布:淘宝身份认证失败 编辑:程序博客网 时间:2024/06/05 06:47

题意:

Alice 和 Bonnie在玩一个游戏,规则如下:

有n个栈,每个栈里有两张照片,每张照片有两个属性ai和bi,含义是,如果Alice拿了这张照片,那么她获得ai分数,如果Bonnie拿到这张照片那么她获得bi分数,以下简称Alice为A,Bonnie为B

这个游戏的最终目的,并不是要想办法让自己的分数最大,而是让自己的分数与对手分数的差值尽可能大。

当然,因为照片是放在栈里的所以只有当栈顶的那张照片被拿走后,才能拿栈底的那张照片


现在由A先手,AB轮流操作,每次可以选择任意拿走一张照片(前提是拿得到)或者不执行任何操作,游戏结束,当所有照片被拿完或是双方连续不操作。问在规则下,A得到的分数-B得到的分数的最大值是多少?


solution:

对同一个栈内的两张照片分析

不妨用四个数字a,b,c,d表示一个栈,代表第一张照片能给A贡献a分,B贡献b分,c,d类似

若a + b >= c + d,这时,无论双方谁先拿了这个栈栈顶的照片,谁都不会让自己的局势更劣

因为a - d >= b - c或是b - c >= d - a

但是如果反过来,a + b < c + d,难道AB都不愿意先手?

事实上,若a > d,因为a - d < c - b,虽然A先手拿这个栈的照片得到的收益不如后手,但是至少对自己的局势有所贡献,另一方面,这时候b - c < d - a < 0,如果B先手,承受的扣分会更严重一些,所以B绝对不会在这个栈先手。因此这个栈等价于一张价值(a-d,d-a)的照片,总是会被记入答案

同理,当b > c,这个栈等价于一张价值(c-b,b-c)的照片,且一定会被记入答案

如果上述两种情况都不发生,无论谁在这个栈先手,另一方总能通过马上在这个栈拿走栈底照片,让自己的局势更优,因此,谁都不会在这样的栈做任何操作

这样,就剩下那些a + b >= c + d的照片了,既然谁都希望在这样的栈先手,那当然是每次取价值最大的照片了

不过这个价值是考虑双方面的,把一张(a,b)的照片替换成(a+b,a+b),然后答案加上a-b

A取这张照片,a+b+a-b = 2a,B取这张照片,a-b-a-b = -2b

那么也就能维护了,开个堆或者排序一下,每次取最大

#include<iostream>#include<cstdio>#include<queue>#include<vector>#include<bitset>#include<algorithm>#include<cstring>#include<map>#include<stack>#include<set>#include<cmath>#include<ext/pb_ds/priority_queue.hpp>using namespace std;const int maxn = 1E5 + 10;typedef long long LL;int n;LL ans;priority_queue <LL> Q;void Add(int x,int y){ans += 1LL*(x-y);Q.push(x+y);}int main(){#ifdef DMCfreopen("DMC.txt","r",stdin);#endifcin >> n;for (int i = 1; i <= n; i++) {int a,b,c,d;scanf("%d%d%d%d",&a,&b,&c,&d);if (a + b >= c + d) Add(a,b),Add(c,d);else if (a > d) ans += 2LL*(a-d);else if (b > c) ans += 2LL*(c-b);}LL cur = 1;while (!Q.empty()) {ans += cur*Q.top();Q.pop(); cur *= -1;}cout << ans/2LL;return 0;}

0 0
原创粉丝点击