gym102155A Ability Draft

二分抄程式碼發表於2020-12-06

https://codeforces.com/gym/102155/problem/A

直接按順序博弈搜尋,維護一隊減二隊的值,每個人可能有兩種選擇,要麼選當前大招中最大的,要麼選普通技能中最大的,如果當前是一隊的人就留返回值較大的,否則留返回值較小的

由於每個人最多隻有4個技能,一共只有10個人,那麼其實選大招的不同的位置就只有4^10種可能,剩下的就是直接按順序選大的

#include<bits/stdc++.h>
using namespace std;
 
const int maxl=1e4+10;
 
int n,s,ps,pu,ans;
int ord[maxl],sa[maxl],ua[maxl],cnt[maxl];
vector<int> xs[maxl];
bool vis[maxl];
 
inline bool cmp(const int &x,const int &y)
{
	return x>y;
}
 
inline void prework()
{
	scanf("%d%d",&n,&s);
	for(int i=1;i<=2*n*(s+1);i++)
	{
		scanf("%d",&ord[i]);
		xs[ord[i]].push_back(i);
	}
	scanf("%d",&ps);
	for(int i=1;i<=ps;i++)
		scanf("%d",&sa[i]);
	sort(sa+1,sa+1+ps,cmp);
	scanf("%d",&pu);
	for(int i=1;i<=pu;i++)
		scanf("%d",&ua[i]);
	sort(ua+1,ua+1+pu,cmp);
}
 
inline int dfs(int k,int sid,int uid)
{
	if(k>2*n*(s+1))
		return 0;
	if(ord[k]<=n)
	{
		int mx=-1e9;
		if(cnt[ord[k]]<s)
		{
			cnt[ord[k]]++;	
			mx=max(mx,dfs(k+1,sid+1,uid)+sa[sid+1]);
			cnt[ord[k]]--;
		}
		if(!vis[ord[k]])
		{
			vis[ord[k]]=true;
			mx=max(mx,dfs(k+1,sid,uid+1)+ua[uid+1]);
			vis[ord[k]]=false;
		}
		return mx;
	}
	else
	{
		int mi=1e9;
		if(cnt[ord[k]]<s)
		{
			cnt[ord[k]]++;
			mi=min(mi,dfs(k+1,sid+1,uid)-sa[sid+1]);
			cnt[ord[k]]--;
		}
		if(!vis[ord[k]])
		{
			vis[ord[k]]=true;
			mi=min(mi,dfs(k+1,sid,uid+1)-ua[uid+1]);
			vis[ord[k]]=false;
		}
		return mi;
	}
}
 
inline void mainwork()
{
	for(int i=1;i<=2*n;i++)
		vis[i]=false,cnt[i]=0;
	ans=dfs(1,0,0);
}
 
inline void print()
{
	printf("%d\n",ans);
}
 
int main()
{
	prework();
	mainwork();
	print();
	return 0;
}

 

相關文章