P5963 [BalticOI ] Card 卡牌游戏
P5963 [BalticOI ] Card 卡牌游戏
题目传送门:https://www.luogu.com.cn/problem/P5963
简述题意:给定
求最值,想到
对于两组数 {
假设
情况一:
情况二:
假设我们取了情况一,因为满足条件,所以我们可以得到:
发现不等式两边下标不同,不妨改变一下式子的形式,将两边的
这时我们就会惊奇的的发现,这不就是二者的和吗?
所以我们可以得出结论:
当一组数的和的值大于另一组时,我们选择让和大的那一组作为减数,小的那一组作为加数。
代码实现也很简单,对于原序列按和从小到大排序,取前
(记得开 long long)
完整代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
const int N=5e6+10;
int n;
struct node{
ll a,b,sum;
}x[N];
bool cmp(node xw,node yw){
return xw.sum<yw.sum;//按和排序
}
ll ans=0;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&x[i].a,&x[i].b);
x[i].sum=x[i].a+x[i].b;
}
sort(x+1,x+n+1,cmp);
for(int i=1;i<=n/2;i++){
ans+=min(x[i].a,x[i].b);//前 n/2 个作为加数
}
for(int i=n/2+1;i<=n;i++){
ans-=max(x[i].a,x[i].b);// 后面的作为减数
}
printf("%lld",ans);//输出结果
return 0;
}