hdu1052 田忌赛马 —— 贪心
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1052
错误代码:
#include<stdio.h>//田忌赛马,错误版 #include<string.h> #include<stdlib.h> /*思路:用田忌最快的马与齐王最快的马比较,1.若能赢就赢;2.若赢不了,就用最差的马拖齐王最好的马入水;3.若打平:要判断是否在最好一匹马, 若是,则打平,若不是,则用最差的一匹马拖它下水,虽然输了这次,但下次有机会赢回。看似无差别,但这样做却保留了最多的好马。 然而这种思靠虽然完备,但方向一开始已经错了。为什么田忌自己赛会输,因为他用最好的马与最好的马去比,硬碰硬。然而孙膑的想法是 避其锋芒,攻其弱点,也就是说,要赢比赛,就要尽量在齐王的弱马上赢,因为这样成本低,收益更大。而不是在齐王的强马上赢得比赛。 所以比赛从齐王最弱的马开始kill。 int cmp(const void*a, const void*b) { return *(int*)b - *(int*)a; } int main() { int n,i,j,m,t[1010],k[1010]; while(scanf("%d",&n) && n) { for(i = 0; i<n; i++) scanf("%d",&t[i]); for(i = 0; i<n; i++) scanf("%d",&k[i]); qsort(t,n,sizeof(t[0]),cmp); qsort(k,n,sizeof(k[0]),cmp); m = 0; int th = 0,tt = n-1,kh = 0; while(kh<n) { if(t[th]>k[kh]) {th++;kh++;m++;} else if(t[th]<k[kh]) {tt--;kh++;m--;} else { if(kh==n-1) {th++; kh++;} else {tt--; kh++; m--;} } } printf("%d\n", m*200); } return 0; }
#include<stdio.h>//正确方案,从弱马开始 #include<string.h> #include<stdlib.h> int cmp(const void*a, const void*b) { return *(int*)b - *(int*)a; } int main() { int n,i,j,m,t[1010],k[1010]; while(scanf("%d",&n) && n) { for(i = 0; i<n; i++) scanf("%d",&t[i]); for(i = 0; i<n; i++) scanf("%d",&k[i]); qsort(t,n,sizeof(t[0]),cmp); qsort(k,n,sizeof(k[0]),cmp); m = 0; int th = 0,tt = n-1,kh = 0,kt = n-1; while(th<=tt) { if(t[tt]>k[kt])//田弱能赢齐弱,则赢 {tt--; kt--; m++;} else if(t[tt]<k[kt])//田弱输齐弱,反正都要死,这匹弱马就要死得最有价值,用它去拖齐强下水 {tt--;kh++; m--;} else { /*田弱平齐弱,总体来说,这匹田弱拿去拖齐强下水,那么田忌获胜的机会更大些,但有例外, 就是万一这匹弱马死得不值呢:田强本来就可以赢齐强,还何必用田弱拖它下水,况且齐弱本可以平局, 这样搞就反而输掉了一局*/ if(t[th]>k[kh])//所以这里要判断田强是否赢齐强,看看田弱是否死得有价值 {th++; kh++; m++;}//死得没价值,这局就让田强赢齐强 else if(t[th]<k[kh])//死得有价值,上吧,田忌会记住你的 {tt--; kh++; m--;} else //田强平齐强,为了保存实力,也让齐弱上(但田弱不一定输)。 { if(t[tt]<k[kh]) m--;//田弱可能平田强,当田强平齐强时,要判断田弱是否真的弱于田强,可能打平 tt--; kh++; } } } printf("%d\n", m*200); } return 0; }