「杂题乱刷」CF1914E1 & CF1914E2

发布时间 2023-12-20 01:41:54作者: wangmarui

题目链接

CF1914E1 Game with Marbles (Easy Version)

CF1914E2 Game with Marbles (Hard Version)

题意简述

\(A\) 和小 \(B\) 想要玩一个游戏,规则是这样的,每个人手里有 \(n\) 种类型的弹珠,每种类型的弹珠数量至少为 \(1\),每次操作方可以扔掉己方的一个类型的一个弹珠(前提是你至少要有这种类型的弹珠),扔完后对方要扔掉所有的与你扔掉这一颗弹珠的所有同类型的弹珠,双方都想让自己的弹珠数量最大,你需要求出小 \(A\) 和小 \(B\) 均使用最优策略的情况下小 \(A\) 的弹珠数量减去小 \(B\) 的弹珠数量的值。

解题思路

觉得不太会 Easy Version 的思路,直接讲 Hard Version 的思路吧。

首先,我们对于每一步策略都考虑一个贡献 \(c_i\),那么我们很容易得出贡献计算的方式就为 \(a_i + b_i = c_i\),其中 \(a_i\) 为小 \(A\) 的每种类型的弹珠数量,\(b_i\) 为小 \(B\) 的每种类型的弹珠数量,然后我们只需要将贡献排一下序,容易得出要使策略最优是必定要优先拿贡献大的地方的,因此直接贪心一下就做完了。

参考代码

/*
Tips:
你数组开小了吗?
你MLE了吗?
你觉得是贪心,是不是该想想dp?
一个小时没调出来,是不是该考虑换题?
*/
#include<bits/stdc++.h>
using namespace std;
#define map unordered_map
#define forl(i,a,b) for(register long long i=a;i<=b;i++)
#define forr(i,a,b) for(register long long i=a;i>=b;i--)
#define lc(x) x<<1
#define rc(x) x<<1|1
#define cin(x) scanf("%lld",&x)
#define cout(x) printf("%lld",x)
#define lowbit(x) x&-x
#define pb push_back
#define pf push_front
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define QwQ return 0;
long long t,n,ans,L,R;
struct node{
	long long a,b,c;
}a[200010];
bool cmp(node x,node y){
	return x.c<y.c;
}
/*
long long t,n,maxn,minn,a[200010],b[200010],vis[200010];
void dfs(bool pd,long long cs,long long sum)
{
	if(cs==n+1)
	{
		maxn=max(maxn,sum);
		minn=min(minn,sum);
		return ;
	}
	if(!pd)
	{
		forl(i,1,n)
			if(!vis[i])
				vis[i]=1,dfs(pd^1,cs+1,sum+a[i]-1),vis[i]=0;
	}
	else
	{
		forl(i,1,n)
			if(!vis[i])
				vis[i]=1,dfs(pd^1,cs+1,sum-b[i]+1),vis[i]=0;
	}
}
void solve()
{
	maxn=-1e18,minn=1e18;
	cin>>n;
	forl(i,1,n)
		cin>>a[i];
	forl(i,1,n)
		cin>>b[i];
	dfs(0,1,0);
	if(n%2)
		cout<<maxn<<endl;
	else
		cout<<minn<<endl;
}*/
int main()
{
	IOS;
	cin>>t;
	while(t--)
	{
		cin>>n;
		forl(i,1,n)
			cin>>a[i].a;
		forl(i,1,n)
			cin>>a[i].b,a[i].c=a[i].a+a[i].b;
		sort(a+1,a+1+n,cmp);
		ans=0,L=1,R=n;
		forl(i,1,n)
		{
			if(i%2)
			{
				if(abs(a[L].c)<=abs(a[R].c))
					ans+=a[R].a-1,R--;
				else
					ans+=a[L].a-1,L++;
			}
			else
			{
				if(abs(a[L].c)<=abs(a[R].c))
					ans-=a[R].b-1,R--;
				else
					ans-=a[L].b-1,L++;				
			}
		}
		cout<<ans<<endl;
	}
    /******************/
	/*while(L<q[i].l) */
	/*    del(a[L++]);*/
	/*while(L>q[i].l) */
	/*    add(a[--L]);*/
	/*while(R<q[i].r) */
	/*	  add(a[++R]);*/
	/*while(R>q[i].r) */
	/*    del(a[R--]);*/
    /******************/
	QwQ;
}