High Card Low Card G(田忌赛马进阶!!)

传送门

\(首先一定要明确一个观点,不然会完全没有思路\)

\(\bullet\)\(由于前半段大的更优,后半段小的更优。\)
\(\bullet\)\(所以,\)Bessie\(一定会在前(n/2)轮比拼中打出自己最大的(n/2)张牌。\)
\(\bullet\)\(那么,因为出的牌确定了,所以我们把比拼分为前半段和后半段。\)

\(前半段(大的牌赢)\)

\(\bullet\)因为\(Bessie可以根据Elsie的出牌顺序调整自己的出牌顺序,所以Elsie前半段怎么出牌都是一样的\)

\(那不妨把 Elsie的前(n/2)张牌从大到小排序\)
\(那我们把Bessie的最大的(n/2)张牌从大到小排序\)

策略
\(\bullet\)\(Bessie最大牌能赢Elsie的最大牌,那就赢。(能赢为什么不赢?)\)

\(\bullet\)\(Bessie最大牌输给Elsie的最大牌,那一定会输,不妨用最小的牌输给他。\)

后半段也是相同的策略。

扩展

\(但是田忌赛马中,规则更加复杂。\)

\(赢了赚钱,输了亏钱,平局不赚不亏\)

\(所以在上面策略的基础上多了一种情况,要是最大马相同怎么办?\)

\(\bullet\)若田忌的最慢马快与齐王的最慢马,两者比(能赢就赢呗)

\(\bullet\)其他,用田忌的最慢马与齐王的最快马比(贡献最大)

#include <bits/stdc++.h>
using namespace std;
int n;
int a[25009],c[25009],b[100009];
int q[25009],h[25009];
bool com(int a,int b){
	return a>b;
} 
int main()
{
	cin>>n;
	int ans=0;
	for(int i=1;i<=n/2;i++)
	{
		cin>>a[i];
		b[a[i]]=1;
	}
	for(int i=1;i<=n/2;i++)
	{
		cin>>c[i];
		b[c[i]]=1;
	}
	sort(a+1,a+1+n/2,com);//前半段大到小 
	sort(c+1,c+1+n/2);//后半段小到大
	for(int i=2*n;i>=1;i--)
	{
		if(q[0]<n/2&&b[i]==0)
			q[++q[0]]=i;
		else if(q[0]>=n/2&&b[i]==0)
			h[++h[0]]=i;	
	} 
	sort(q+1,q+1+n/2,com);//前半段大到小
	sort(h+1,h+1+n/2);//后半段小到打 
	int p1=1,p2=1,w1=n/2,w2=n/2;
	while(p1<=w1)
	{
		if(q[p1]>a[p2])
			ans++,p1++,p2++;
		else
			w1--,p2++;
	}
	p1=1,p2=1,w1=n/2,w2=n/2;
	while(p1<=w1)
	{
		if(h[p1]<c[p2])
			ans++,p1++,p2++;
		else
			w1--,p2++;	
	} 
	cout<<ans;
}
posted @ 2020-04-13 10:41  倾叶子佮  阅读(188)  评论(0编辑  收藏  举报