p1620田忌赛马(贪心+模拟)
描述 Description
中国古代的历史故事“田忌赛马”是为大家所熟知的。话说齐王和田忌又要赛马了,他们各派出N匹马,每场比赛,输的一方将要给赢的一方200两黄金,如果是平局的话,双方都不必拿出钱。现在每匹马的速度值是固定而且已知的,而齐王出马也不管田忌的出马顺序。请问田忌该如何安排自己的马去对抗齐王的马,才能赢取最多的钱?
如果不止三匹马,这个问题显然可以用二分图的匹配来解决,但是,现在觉得二分图匹配来解决太先进了,你用一个简单的算法来解决这个问题。
输入格式 Input Format
第一行为一个正整数n,表示双方马的数量。
第二行的N个整数为田忌的马的速度。
第三行有N个整数表示齐王的马的速度。
输出格式 Output Format
仅有一行,为田忌赛马可能赢得的最多的钱。
样例输入 Sample Input
3
92 83 71
95 87 74
样例输出 Sample Output
200
时间限制 Time Limitation
1s
注释 Hint
【数据规模】
20% 1<=n<=65
40% 1<=n<=250
100% 1<=n<=2000
来源 Source
经典例题
思路:第一次的思路是将田忌的马和秦王的马都按照从大到小的排一下序,然后用田忌的马依次和秦王的比,如果田忌的马大就加钱,田忌的马小就让小的马去和秦王比,相等的话就比较下面两只,然后又测了一组数据发现不对。想了想确实,这样的方案并不是最优的。还是先从大到小排一下序,然后如果田忌的马比秦王的大那么+200,然后比较下两只马,如果田忌当前的马比秦王的小,就让小的马去和秦王比。如果相等的话(刚开始忘了讨论相等时候的情况了)如果田忌最小的马比秦王最小的马大,则+200。如果田忌最小的马比秦王最小的马小,如果他还小于秦王当前的马那就只能减钱了。具体看代码你就懂了(没事干刷刷水题还是可以活跃一下思维的)
代码如下:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; inline int read() { char ch=getchar(); int x=0,f=1; while(ch>'9'||ch<'0') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } bool mycmp(int x,int y) {return x>y;} int a[21000],b[21000]; int main() { //freopen("add.in","r",stdin); int n; n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) b[i]=read(); sort(a+1,a+1+n,mycmp); sort(b+1,b+1+n,mycmp); long long ans=0; int i,j,ii,jj; for(i=1,j=1,ii=n,jj=n;i<=ii;) { if(a[i]>b[j]) { ans+=200; j++;i++; } else if(a[i]<b[j]) { ans-=200; ii--;j++; } else { if(a[ii]>b[jj]) { ans+=200; ii--;jj--; } else { if(a[ii]<b[j]) ans-=200; ii--;j++; } } } cout<<ans<<endl; return 0; }