首先,根据田忌赛马的策略,
当第一队的第一个比第二队的第一个小 时,用最小的换最大的
类似的推出,当第一队的第一个比第二队的第一个大 时,用最大的换最大的
同时,从反方向考虑,当第一队的最小的比第二队的最小的大 时,用最小的换最小的
然后就是头尾都相等的情况,有两个策略:
左图:拿1分 , 后面的配对情况不变, 右图,不拿1分,后面的错一位的最差情况
(=相等,虚线小于,实线大于)
右图 注意到每一群相等的线段都至少能使上一个的虚线变成=,或最上面的=变成实线(至少+1)
能使每一群实线保持不变,(至少不变)
能使每一群虚线可能有变成实线(至少不变)
所以右图不会比左图更差
所以如果头两个相等,尾两个相等,就拿尾比头,这样不会是差的
码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define zuo o<<1,l,mid
#define you o<<1|1,mid+1,r
using namespace std;
int a[100005],b[100005],c,ll,rr,op,v[100005<<2],z11,z12,z21,z22,n,i,qsum[100005],ans;
int main()
{
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=1;i<=n;i++)scanf("%d",&b[i]);
sort(a+1,a+1+n);
sort(b+1,b+1+n);
z11=n;z12=1;z21=n;z22=1;
for(i=1;i<=n;i++)
{
if(a[z11]>b[z21])
{
ans+=2;
z11--,z21--;
}else
if(a[z12]>b[z22])
{
ans+=2;
z12++,z22++;
}else
{
if(a[z12]==b[z21])ans+=1;
z12++;z21--;
}
}
printf("%d ",ans);
swap(a,b);
ans=0;
z11=n;z12=1;z21=n;z22=1;
for(i=1;i<=n;i++)
{
if(a[z11]>b[z21])
{
z11--,z21--;
}else
if(a[z12]>b[z22])
{
z12++,z22++;
}else
{
if(a[z12]==b[z21])ans+=1;
else ans+=2;
z12++;z21--;
}
}
printf("%d",ans);
}