CF_725F Family Photos
http://codeforces.com/problemset/problem/725/F
题意:
有n对照片,两个人A和B轮流取。
每对照片有四个值a1,b1,a2,b2,表示第一张和第二张对A和B来说的喜悦值。
轮到一个人时,她可以选择不取,如果连续两轮中A和B都选择不取那么游戏结束。
双方都希望(自己的喜悦值 - 对方的喜悦值)尽量大。
假设两个人都采用最佳策略,求最后A的喜悦值和B的喜悦值的差值。
数据:
1 ≤ n ≤ 100 000, 0 ≤ a1,b1,a2,b2 ≤ 10^9
思路:
1. 贪心。对双方而言,A的目标是(a-b)尽量大,B目标则是使(a-b)尽量小[为负数]。
2. 按照每一对来看,有三种情况:
1) A取第一张;
2) B取第一张;
3) 双方都不取。
3. 我们分类讨论:
1)当 a1 - b2 >= a2 - b1 时,双方都想取第一张。最后的方案取决于这种情况个数的奇偶。
2)当 a1 - b2 < a2 - b1 时,双反都想取第二张,则再讨论:
i)a1 > b2 时,虽然对于A来说不是最优的策略。
但是等到B选择不取的时候,A选择拿第一张的收益 [此时A的收益 > 0] 比 结束比赛 的收益大。
那么A还是会选择取这对的第一张,然后B一定会选择取第二张。
ii)b1 > a1 时,B面临着同样的情况,即B最后等到A选择不取时[相当于A放弃了先手],选择拿第一张,然后A拿第二张。
iii) 当 a1 <= b2 且 b1 <= a2 时,双方都选择忽视这对照片。
4. 最后总结起来相对于A的收益:
1 = 排序后分奇偶:(a1 - b2 ) 或者(a2 - b1)
2.1 = (a1 - b2 )
2.2 = (a2 - b1 )
2.3 = 0
代码
// CF 725_F Canada Cup 2016
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <bitset>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <iomanip>
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const double eps=1e-6;
const int N=100005;
const int MOD=1000;
const int M=1e9+7;
const int INF=0x3f3f3f3f;
const int mod=1000000007;
const double pi=acos(-1.0);
int n,m;
int a1,a2,b1,b2;
int s[N*2];
int main()
{
while (~scanf("%d",&n))
{
memset(s,0,sizeof(s));
int pos=0;
LL ans=0;
for (int i=0;i<n;i++)
{
scanf("%d%d%d%d",&a1,&b1,&a2,&b2);
if (a1+b1>=a2+b2)
{
s[pos++]=a1+b1;
s[pos++]=a2+b2;
ans+=a1+a2;
}
else if (a1>b2)
ans+=a1-b2;
else if (b1>a2)
ans+=a2-b1;
}
sort(s,s+pos);
for (int i=0;i<pos;i+=2)
ans-=s[i];
printf("%I64d\n",ans);
}
return 0;
}
/*
2
12 3 4 7
1 15 9 1
2
5 4 8 8
4 12 14 0
1
0 10 0 10
*/
//Ans : 1 4 -10
本文解析了CodeForces 725F问题——Family Photos的解决思路,通过贪心策略来确定两人A和B在轮流取照片时的最佳策略,以最大化各自收益与对手收益之差,并提供了实现代码。
598

被折叠的 条评论
为什么被折叠?



