先把两队人从大到小排一遍序
每次比较两队的队首和队尾(队首是本队最强的,队尾是本队最弱的)
最好的情况下(我方得分最多时)
①如果我方的队首大于对方的队首,用我方队首打败对方队首,显然最优
②我方的队尾大于对方队尾,说明我方所有的人都可以打败对方的队尾,所以消耗一个最弱的来打他,显然最优
③如果我方队首和队尾都比对方弱,(怎么着都得输一局),就用我队最弱的牵制对方最强的,这样会使最弱的人死得更有价值(23333)
④除了以上这些情况,只要任意一对平手或队首队尾都是平手,就让我方队尾去打对方队首,可以手推,三种情况中,这样都是最优的。
而对于最坏的情况,这里有一个小技巧,就是,用同样的方法求出对方最大可能获得的分数,因为每一局无论谁输谁赢或平手,两者的得分之和都是2,所以两队每次总的得分之和是2*n。因此,最坏情况下,我方的分是2*n–对方最好得分
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;
int n,ans[3];
int num[3][maxn];
bool cmp(int x,int y)
{
return x>y;
}
void done(int k1,int k2)
{
int mf=1,ml=n,tf=1,tl=n;
for(int i=1;i<=n;++i)
{
if(num[k1][ml]>num[k2][tl])
{
ans[k1]+=2;
ml--;
tl--;
}
else if(num[k1][mf]>num[k2][tf])
{
ans[k1]+=2;
mf++;
tf++;
}
else
{
if(num[k1][ml]==num[k2][tf]) ans[k1]++;
ml--;
tf++;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&num[1][i]);
for(int i=1;i<=n;++i) scanf("%d",&num[2][i]);
sort(num[1]+1,num[1]+n+1,cmp);
sort(num[2]+1,num[2]+n+1,cmp);
done(1,2);
done(2,1);
ans[2]=(n<<1)-ans[2];
printf("%d %d",ans[1],ans[2]);
return 0;
}