卧薪尝胆,厚积薄发。
ZJOI2008 泡泡堂
Date: Wed Aug 01 15:00:04 CST 2018 In Category: NoCategory

Description:

进行 $n$ 场比赛。每胜一场比赛得 $2$ 分,平一场得 $1$ 分,输一场不得分。已知己方和对方每方 $n$ 个人的水平,问最好和最坏情况下己方能得几分。
$1\le n \le 100000$

Solution:

按照田忌赛马的策略,每次先看最大的能不能打过对方最大的能打则打,因为这样可以把较小的留给后面,一定不亏,最大的打不了,就拿一个最小的去顶,但这样不一定最优,原因是可能有相同的值,当有相同的值时,可能用最大打最大得一分更优,于是应看最小的能不能打掉最小的,如果能打掉,不如先打掉。
最坏情况可以对对方做一遍相同算法,再用 $2\times n$ 减掉。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n;
#define MAXN 100010
int a[MAXN],b[MAXN];
int *x = a,*y = b;
bool cmp(int a1,int a2){return a1 > a2;}
int work()
{
int score = 0;
for(int xi = 1,xj = n,yi = 1,yj = n;xi <= xj;)
{
if(x[xi] > y[yi]){score += 2;++xi;++yi;continue;}
else
{
if(x[xj] > y[yj]){score += 2;--xj;--yj;continue;}
else{if(x[xj] == y[yi])++score;++yi;--xj;continue;}
}
}
return score;
}
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;++i)
{
scanf("%d",&x[i]);
}
for(int i = 1;i <= n;++i)
{
scanf("%d",&y[i]);
}
sort(x + 1,x + 1 + n,cmp);
sort(y + 1,y + 1 + n,cmp);
cout << work() << " ";
swap(x,y);
cout << 2 * n - work() << endl;
return 0;
}
In tag: 算法-贪心
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡