首页 > 其他分享 >CF1875B Jellyfish and Game

CF1875B Jellyfish and Game

时间:2023-10-01 10:35:14浏览次数:39  
标签:CF1875B 第一个 最大值 交换 Game 最小值 sb sa Jellyfish

思路

题意大概是两人都有一组数,奇数轮,第一个人可以选择和第二个人交换一个数字也可以不换,偶数轮,第二个人可以选择和第一个人交换一个数字也可以不换。

首先可以猜测,我们每次都应该选择交换对方的最大值和自己的最小值,如果自己的最小值都比对方大的话就不交换。应该比较好想,这里感性证明一下。

如果用的不是自己的最小值去交换,那么总和会变小,对方也不会再交换你的最小值,所以这一步是亏的。

如果交换的不是对方的最大值,如果这个值本身就是你的最大值,那么对方又换回来,没有影响,如果不是,对方交换回去,你就损失了你的最大值,比你交换对方的最大值会亏损一些总和。

如果不需要交换而强制交换,那么会让自己的总和变小,对方再交换一次,又亏损一定的答案,不值得。

那么知道这个性质,我们可以推测,大部分的游戏都一个讨论,两个人把两个数交换过去交换过来,所以我们不需要模拟,可以直接跳过许多无用的游戏。

因为 \(k\) 的奇偶决定着谁结束游戏,也就是最后是谁交换的,这个信息是很重要的,所以我们可以考虑分成奇偶两种情况分别考虑。

首先,当 \(k\) 是奇数时,由第一个人结束游戏,所以如果第二个人的最大值比第一个人的最小值还要小的话,第一个人第一轮不交换,后续第二个人交换啥,第一个人就交换回来,所以答案不变。否则的话,第一个人会交换自己的最小值和对方的最大值,然后两人开始互相交换,最后第一个人交换成功,所以答案是原来的总和加上对方的最大值和自己的最小值。

然后,当 \(k\) 是偶数时,由第二个人结束游戏,和上面一种情况比较相似,如果第二个人的最大值比第一个人的最小值还要小,那么第一轮,第一个人不会交换,那么后续第二个人就可以成功交换,所以答案是总和减去第一个人的最大值加上第二个人的最小值。否则,答案不变。

想清楚了后,发现很简单,只需要在输入的时候记录两个人的最大最小值即可。

快速地写完,发现 WA 了。

思考了一下,发现当对方的最大值交换过来不是自己的的最大值时,就不是互相交换两个数,答案的变化也没有这么简单。

所以我们可以考虑先计算交换两轮的结果,第一轮可以保证最大值在第一个人身上,第二轮可以保证最大值在第二个人身上,并且最小值在第一个人身上,这样每次都必定交换最小值和最大值。

证明比较简单,第一轮如果最大值在自己身上,无论交不交换,最大值都还是自己的,如果不在自己身上,则必然交换,最大值就是第一个人的了。第二轮,第二个人必定交换,最大值就跑到第二个人身上了,第二个人会把自己的最小值给第一个人,所以第一个人同时有了自己和第二个人的最小值,所以最小值一定在第一个人身上。

所以我们可以先模拟两次过程,再上面的结论即可。

AC code

#include<bits/stdc++.h>
using namespace std;
long long T,n,m,k,sum1,sum2,minn,maxn,t,mi,ma;
multiset<long long>sa,sb;
int main()
{
	scanf("%lld",&T);
	while(T--)
	{
		scanf("%lld%lld%lld",&n,&m,&k),sum1=sum2=0,sa.clear(),sb.clear();
		for(int i=1;i<=n;++i) scanf("%lld",&t),sum1+=t,sa.insert(t);//分别用set存下来
		for(int i=1;i<=m;++i) scanf("%lld",&t),sum2+=t,sb.insert(t);
		for(int i=1;i<=2&&i<=k;++i)//模拟2次,注意k<=2的情况
		{
			if(i%2)
			{
				auto a=sa.begin(),b=sb.end();--b;
				if(*b-*a>0) sum1+=*b-*a,sum2+=*a-*b,sa.insert(*b),sb.insert(*a),sa.erase(a),sb.erase(b);
			}
			else
			{
				auto a=sa.end(),b=sb.begin();--a;
				if(*a-*b>0) sum1+=*b-*a,sum2+=*a-*b,sa.insert(*b),sb.insert(*a),sa.erase(a),sb.erase(b);
			}
		}
		k-=2;
		auto mina=sa.begin(),maxa=sa.end(),minb=sb.begin(),maxb=sb.end();--maxa,--maxb;//用set直接找到双方的最大最小
		if(k<=0) printf("%lld\n",sum1);
		else if(k%2) printf("%lld\n",sum1+max(*maxb-*mina,0ll));
		else printf("%lld\n",(*maxb<*mina)?sum1-max(*maxa-*minb,0ll):sum1);//上面的结论
	}
	return 0;
}

标签:CF1875B,第一个,最大值,交换,Game,最小值,sb,sa,Jellyfish
From: https://www.cnblogs.com/One-JuRuo/p/17738630.html

相关文章

  • CF1875D Jellyfish and Mex
    思路看到\(n\)的范围只有\(5000\),并且\(\sumn\)的范围也是\(5000\),所以可以考虑\(n^2\)的做法。每次操作肯定都是一次性删完某个数字,如果删除某个数字删一半又去删别的数字,答案肯定会变大。所以我们可以考虑统计所有数字的数量,记为\(num_i\),来计算删完某个数字的最小......
  • CF1875C Jellyfish and Green Apple
    思路首先我们可以考虑把能分的都先分了,再选择去切剩下的苹果。那么我们只需要考虑苹果数量少于人数的情况,每个人能分的苹果都必然少于目前的单个苹果,所以每个苹果都必须切一刀,那么答案数就会增加当前的数量,再把能分的都分了,重复这一过程,直到分完为止。这样去切一定是最优的。那......
  • 题解 CF1875D【Jellyfish and Mex】
    显然,除非\(\operatorname{mex}a=0\),否则不会删除\(>\operatorname{mex}a\)的数。而\(\operatorname{mex}a=0\)时不对答案产生贡献,因此任意时刻我们都可以忽略\(a\)中\(>\operatorname{mex}a\)的数。又显然,一旦我们开始删一个数,就会先把所有与之相等的数删光。否则,设最先......
  • UTPC 2021 L Maze Game
    洛谷传送门AtCoder传送门若图中存在点使得删去它后\(S,T\)不连通,那么A可以一步获胜。否则,双方都不会删去一个点使得删去它后会产生一个点使得删去它后\(S,T\)不连通。那么到最后图上会剩下两条\(S\toT\)的不交路径。此时一方无论如何操作都会使得另一方获胜。因......
  • Galgame封包逆向入门
    Galgame封包逆向入门这里就简单聊一下封包逆向分析的一些注意点吧,其实也是初入逆向的注意点了,本质差不多。正向基础语言基础:ASM、C、C++平台基础:Win32、PE、GDI、DirectX引擎基础:游戏引擎架构虽然说的逆向,其实和正向的水平、见识、经验是强相关的,如果你没写过相关的程序又......
  • GameFi链游系统开发应用
      GameFi软件的开发是结合了区块技术,它是将游戏的元素移动到上链上,让游戏变得独立,这就符合了用户的娱乐方式。该软件项目还具有一定的投资价格,GameFi系统开发的应用可以带来更多的创新和价值。  GameFi的软件开发应用程序是让用户更好的管理自己的资产,有助于游戏的稳定,持......
  • CF1882C Card Game
    某种程度上的抽卡游戏?有这样一个结论:一个后缀中\([i+1,n]\)中所有的正数都可以被取到,所以维护一个正数后缀和\(s_i\),枚举每个位置\(i\),如果\(i\)为奇数,答案对\(a_i+s_{i+1}\)取\(\max\),否则对\(s_{i+1}\)取\(\max\)。下面证明这个结论:先依次取掉\([i+1,n]\)中的奇......
  • Strategic game POJ - 1463 树的最小点覆盖,树形dp
    题意:树的最小点覆盖,选择最少的点覆盖所有边。分析:状态:f[u][0/1]表示不选/选编号u的点的最优解转移:不选u,则一定选u的儿子v,即f[u][0]+=f[v][1]选u,则可以选,也可以不选u的儿子v,即f[u][1]+=min(f[v][0],f[v][1]);目标:ans=min(f[rt][0],f[rt][1]);点击查看代码#inc......
  • Python游戏开发:Pygame库入门
    Pygame是一个开源的Python库,用于开发2D游戏。它提供了许多功能,如游戏开发、音频处理和事件处理。安装Pygame库您可以通过以下命令在终端中安装Pygame库:pipinstallpygame创建游戏窗口要创建一个游戏窗口,您可以使用以下代码:importpygamepygame.init()#设置窗口尺寸window_......
  • [CF235D] Graph Game
    GraphGame乌克兰逃兵在线发题解。好像要用期望去推,但是像我这种看到序列的期望题只想得到线性性的弱鸡只能感理了。我们把点分治过程当成点分树,y能在x被爆时做贡献当且仅当y为x的子树。先考虑树的情况。考虑把遍历t的次数分到单个点上发现仅当x为x->y路径上......