专栏文章
题解:CF725F Family Photos
CF725F题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mion236l
- 此快照首次捕获于
- 2025/12/02 21:53 3 个月前
- 此快照最后确认于
- 2025/12/02 21:53 3 个月前
好妙好可爱的贪心啊,只是我太弱想不完,还要学长的提示。
翻译是*。
题目大意:
有 组照片,每组照片有两张,第一张对于 的贡献分别为 ,第二张为 ,取了第一张才能取第二张。两人都采取最优策略使自己的贡献和比对方尽可能大得多,问最后 和 的差值。
思路:
对于一组照片:
1.对于 的情况,即后手更优(或者一样):
-
我们假设 ,则也有 。那么不管 是先手还是后手都是稳赚不赔, 都是亏。那么我们不妨把这些照片组放在后面, 没有其它选的时候就必然选第一张了,而 为防止 赚更多会把第二张取掉。
-
的情况同理, 先手就好了。
-
如果谁先手都会亏,即 ,那这牌就废了,傻子才取。
2.对于 的情况,即先手更优:
-
先假设如果每组只有一张照片,那么就是 和 交替取。若取第 组比取第 组好,当且仅当 即 ,排个序就可以了。
-
那一组照片其实就可以拆开成两张了,因为第一张 的和总是大于第二张,所以排序后总是先取 再取 ,非常满足条件,然后 交替取就行了。非常细节的问题就不加以解释了,想想就会了(本菜鸡就是这样)。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 200005//拆成两张双倍空间
int n;
struct node{
int a,b;
}a[N];
inline int read(){
int a=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
a=a*10+c-'0';
c=getchar();
}
return a*f;
}
bool cmp(node a,node b){
return a.a+a.b>b.a+b.b;
}
main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read();
int ans=0,cnt=0;
for(int i=1;i<=n;i++){
int a1=read(),b1=read(),a2=read(),b2=read();
if(a1-b2>a2-b1){//先手优,先存起来,两张照片分开
a[++cnt].a=a1,a[cnt].b=b1;
a[++cnt].a=a2,a[cnt].b=b2;
continue;
}
if(a1-b2<=0&&b1-a2<=0)continue;//后手优,但先手<=0,不取
if(0<a1-b2)
ans+=a1-b2;//a先手>0
else
ans+=a2-b1;//b先手>0
}
sort(a+1,a+1+cnt,cmp);
for(int i=1;i<=cnt;i++){//交替给a和b
if(i%2)
ans+=a[i].a;
else
ans-=a[i].b;
}
printf("%lld\n",ans);
return 0;
}
希望自己能记住这题,这题解写得不容易,这题也不容易。
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...