您的位置:首页 > 其它

田忌赛马(贪心)

2016-06-20 22:06 260 查看
[align=left]http://acm.hdu.edu.cn/showproblem.php?pid=1052[/align]
[align=left]思路完全偏了,百思不得其解,看了题解。[/align]
[align=left]先转为敬
http://www.cnblogs.com/anderson0/archive/2011/05/07/2039971.html[/align]
[align=left]题意:田忌赛马。大王有n匹马,田忌也有n匹马。田忌每赢一局得200银币,输一局-200银币,平局钱数不变。那么问题来了,田忌最多能获得多少银币?[/align]
[align=left]分析:[/align]
[align=left]一.策略[/align]
[align=left]首先是每次都用田忌最快的马与大王最快的马比[/align]
[align=left]1.如果田忌最快的马快,就用田忌最快的马,赢了大王最快的马。[/align]
[align=left]2.如果大王最快的马快,就用田忌最慢的马输给大王最快的马。[/align]
[align=left]3.如果是平局需要分类讨论。[/align]

[align=left]    a.当大王最慢的马,比田忌最慢的马慢,此时田忌最慢的马与大王最慢的马比。[/align]

[align=left]    b.当大王最慢的马,比田忌最慢的马快,此时田忌最慢的马与大王最快的马比。[/align]
[align=left]    c.当大王最慢的马与田忌最慢的马一样,此时田忌最慢的马与大王最快的马比。[/align]
[align=left]二.算法证明[/align]
[align=left]1.设大王最快的马K,田忌最快的马T。且田忌的马快。T > K假设不是用大王最快的马,与田忌最快的马比。因为田忌最快的马,不与大王最快的马比,就一定要和大王别的马比。那么设大王与t相比的马为k,显然 k <= K,设田忌的与K相比的马为t,显然t <= T,。[/align]
[align=left]    a.k > t。T > K >= k > t。原来的两局TK比,kt比,田忌赢一局,输一局。现在的两局Tk比,Kt比,同样。不增不减[/align]
[align=left]    b.k = t。T > K >= k = t。原来的两局TK比,kt比,田忌赢一局,平一局。现在的两局Tk比,Kt比,田忌赢一局,平或输一局,不如原来。[/align]
[align=left]    c.k < t。T > K >= k < t <= T。原来的两局TK比,tk比,田忌赢一局,赢一局。现在的两局Tk比,Kt比不一定,田忌赢一局,一局不定,不如原来[/align]
[align=left]    可证,如此取是合适的[/align]
[align=left]2.大王最快的马一定赢,所以要用田忌最慢的马来输。[/align]
[align=left]3.大王与田忌最快的马平局了,此时就要看最慢的马们(???)[/align]
[align=left]    a.田忌最慢的马比大王最慢的马快,证明同1[/align]
[align=left]    b.田忌最慢的马比大王最慢的马慢,所以田忌最慢的马,比大王所有的马都慢。及此马必输,就让此马与最快的比[/align]
[align=left]    c.平局的情况。如果让最快的马与最快的比,最慢的与最慢的比,结果是零。如果让田忌最慢的与大王最快的比,然后用只比大王最慢的马大一点的马与大王最慢的比,这样就保留了田忌最快的马。[/align]
[align=left] [/align]
[align=left]代码:[/align]
/**错误点: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> 


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息