HYSBZ/BZOJ 1034 [ZJOI2008] 泡泡堂BNB - 贪心
分析:
经典贪心题,跟田忌赛马没什么区别。
1. 以最小的代价尽量多的赢
2. 尽量多的平局
3. 剩下的注定要输了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 100000
int n,a[MAXN+10],b[MAXN+10],c[MAXN+10],d[MAXN+10];
int stak[MAXN+10];
bool vis1[MAXN+10],vis2[MAXN+10];
int Greedy(int w[],int l[])
{
sort(l+1,l+n+1);
sort(w+1,w+n+1);
int ret=0;
memset(vis1,0,sizeof vis1);
memset(vis2,0,sizeof vis2);
int top=0,j=n;
for(int i=n;i>=1;i--){
while(j>=1&&w[j]>l[i])
stak[top++]=j--;
if(top>0){
vis2[i]=true;
vis1[stak[top-1]]=true;
top--;
ret+=2;
}
}
int m=0;
for(int i=1;i<=n;i++){
if(!vis1[i])
c[++m]=w[i];
}
m=0;
for(int i=1;i<=n;i++){
if(!vis2[i])
d[++m]=l[i];
}
//此时最多打成平局
j=m,top=0;
for(int i=m;i>=1;i--){
while(j>=1&&c[j]>=d[i])
stak[top++]=j--;
if(top>0){
ret++;
top--;
}
}
return ret;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
printf("%d %d\n",Greedy(a,b),2*n-Greedy(b,a));
}