poj 2287 Tian Ji -- The Horse Racing 题目链接:http://poj.org/problem?id=2287
贪心水
background knowledge:田忌赛马
题目大意:这次赛马不同往常,由特殊推广到了一般。首先,马不分上中下三等,而是有能力值;其次,不只有三匹马参加比赛,而是n匹(n由键盘输入)。Description中提到了二分图的最大匹配,是解决这个问题的一种方法,另外DP也行,我现在只会贪心,以后会回来的。
题目分析:田忌和齐王的马分别sort之后从小向大找。
现有原则如下:
一、田忌最慢的马如果比齐王最慢的马快,那就皆大欢喜,用这两匹马比就可以了;
二、田忌最慢的马如果比齐王最慢的马慢,那这匹马就是场上最慢的马了,它的唯一作用就是消耗掉当前齐王最快的马;
三、如果双方最慢的马一样快慢,就要比他们最快的马了(这里之前一直没想到,所以不知道怎么比)
1、田忌最快的马比齐王最快的马快,那么这匹马是场上最快的马,让它去消耗掉齐王最快的马,最合适;
2、田忌最快的马不比齐王最快的马(这里有两种情况),就用田忌最慢的马去拼齐王最快的马。
原则分析:上几条显然,最后的“三、2”可能需要解释一下,两种情况中,田忌最快的马慢于齐王最快的马就不用说了,拿自己最慢的马消耗掉场上最快的马;双方最快的马等速的时候,用数学分析法(课本上写的挺多,大家自己证一下吧)可得最合适的方法如上。
code:
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
int n,i,j,tj[1050],king[1050];
while(scanf("%d",&n)!=EOF&&n)
{
for(i=1;i<=n;i++)
{
scanf("%d",&tj[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&king[i]);
}
sort(tj+1,tj+n+1);
sort(king+1,king+n+1);
int tl=1,tr=n,kl=1,kr=n,money=0;
while(tl<=tr)
{
if(tj[tl]>king[kl])money+=200,tl++,kl++;
else if(tj[tl]<king[kl])money-=200,tl++,kr--;
else while(tl<=tr)
{
if(tj[tr]>king[kr])money+=200,tr--,kr--;
else
{
if(tj[tl]<king[kr])money-=200;
else if(tj[tl]>king[kr])money+=200;
tl++;kr--;break;
}
}
}
printf("%d\n",money);
}
return 0;
}
PS:花了将近一天,小错不断。手生了,sort都不会用了……还遇见个奇葩网站“泡面吧”,绝对正确的程序居然编不出来(CE),不信去看看第七题和第六十八题。