思路完全偏了,百思不得其解,看了题解。
题意:田忌赛马。大王有n匹马,田忌也有n匹马。田忌每赢一局得200银币,输一局-200银币,平局钱数不变。那么问题来了,田忌最多能获得多少银币?
分析:
一.策略
首先是每次都用田忌最快的马与大王最快的马比
1.如果田忌最快的马快,就用田忌最快的马,赢了大王最快的马。
2.如果大王最快的马快,就用田忌最慢的马输给大王最快的马。
3.如果是平局需要分类讨论。
a.当大王最慢的马,比田忌最慢的马慢,此时田忌最慢的马与大王最慢的马比。
b.当大王最慢的马,比田忌最慢的马快,此时田忌最慢的马与大王最快的马比。
c.当大王最慢的马与田忌最慢的马一样,此时田忌最慢的马与大王最快的马比。
二.算法证明
1.设大王最快的马K,田忌最快的马T。且田忌的马快。T > K假设不是用大王最快的马,与田忌最快的马比。因为田忌最快的马,不与大王最快的马比,就一定要和大王别的马比。那么设大王与t相比的马为k,显然 k <= K,设田忌的与K相比的马为t,显然t <= T,。
a.k > t。T > K >= k > t。原来的两局TK比,kt比,田忌赢一局,输一局。现在的两局Tk比,Kt比,同样。不增不减
b.k = t。T > K >= k = t。原来的两局TK比,kt比,田忌赢一局,平一局。现在的两局Tk比,Kt比,田忌赢一局,平或输一局,不如原来。
c.k < t。T > K >= k < t <= T。原来的两局TK比,tk比,田忌赢一局,赢一局。现在的两局Tk比,Kt比不一定,田忌赢一局,一局不定,不如原来
可证,如此取是合适的
2.大王最快的马一定赢,所以要用田忌最慢的马来输。
3.大王与田忌最快的马平局了,此时就要看最慢的马们(???)
a.田忌最慢的马比大王最慢的马快,证明同1
b.田忌最慢的马比大王最慢的马慢,所以田忌最慢的马,比大王所有的马都慢。及此马必输,就让此马与最快的比
c.平局的情况。如果让最快的马与最快的比,最慢的与最慢的比,结果是零。如果让田忌最慢的与大王最快的比,然后用只比大王最慢的马大一点的马与大王最慢的比,这样就保留了田忌最快的马。
代码:
/**错误点:1贪心错了,应该是每次用田忌最快的马,与齐王最快的马比,如果田忌的快,赢之,如果齐王的快则田忌用最慢的马赫他玩儿
如果平局,此时要进行特殊处理:
2简单的认为平局打还是不打是不正确的**/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int t[1005],k[1005];
bool idx[1005];
bool cmp(int a,int b)
{
return a > b;
}
int main()
{
//freopen("in.txt","r",stdin);
int n;
while(1)
{
scanf("%d",&n);
if(n == 0)
break;
memset(idx,false,sizeof(idx));
int ans = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d",&t[i]);
}
for(int i = 0; i < n; i ++)
{
scanf("%d",&k[i]);
}
sort(t, t + n,cmp);
sort(k, k +n,cmp);
int tk = 0,tm = n - 1,kk = 0,km = n - 1;//tk田忌最快的,tm田忌最慢的。kk国王最快的,km国王最慢的
while(n --)
{
if(t[tk] > k[kk])
{
tk ++;
kk ++;
ans ++;
}
else if(t[tk] < k[kk])
{
tm --;
kk ++;
ans --;
}
else
{
if(t[tm] <= k[km])
{
if(t[tm] < k[kk])
{
ans --;
}
tm --;
kk ++;
}
else
{
tm --;
km --;
ans ++;
}
}
}
printf("%d\n",ans * 200);
}
return 0;
}
<span style="font-size:18px;"></span>