田忌赛马
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1052
题目描述:对于英语战五渣的我表示看起来很吃力,不过大概的意思就是两队人各有一组马
每个马都有一个权值(速度),每次各挑一匹来比赛,求最大的胜出利益
解题思路:其实这属于变相的贪心问题,唯一的差别就是 贪心往往 走一步看一步直到走完,也就是从开始到结束一条线
而本题我们把马排序当成一个序列,采取最优配对方案,可能是头(最快),也可能是尾(最慢),从一根筋升级成为两头堵~!2333
配对方案就是:
如果我方最快的马比对方最快的马快:我方最快的马与对方最快的马比
如果我方最快的马没有对方最快的马快:我方最慢的马与对方最快的马比
这两种情况的解决方案比较明显,重点是持平该如何处理
举个例子 最快的马持平,如果保持持平,下一组可能也会持平,那么就会一直平下去。如果采取最次的马输一次,那么就可以保证后续一直处于赢的状态
但是假设每组就剩两匹马,最次的马可以胜过对方最次的马,那么我采取刚才所说的方案结果就是各赢一次,其实我是可以1平1胜的。
所以当最快的马相比处于持平的状态时,要循环着考虑末端的马,如果末端的马不大于对方的马,那么反正也是得输一次(或者平),还不如消耗对方最快的马
如果最慢的马大于对方最慢的马,那就先赢一次再说,发挥其最大的价值。
也就是这道题想比贪心,要从两方面考虑。既要考虑最快马的利用价值,也要考虑最慢的马的利用价值。
#include<stdio.h>int main(){int tj;int t[1001],g[1001];int h,i,j,k,n,m,temp,dj,dk,ddj,ddk;while(scanf("%d",&n)&&n){tj=0;for(i=1;i<=n;i++)scanf("%d",&t[i]);for(i=1;i<=n;i++)scanf("%d",&g[i]);//===========================================for(i=1;i<n;i++)for(j=1;j<n-i+1;j++){if(t[j]<t[j+1]){temp=t[j];t[j]=t[j+1];t[j+1]=temp;}if(g[j]<g[j+1]){temp=g[j];g[j]=g[j+1];g[j+1]=temp;}}//===========================================k=j=1;m=n;for(i=1;i<=n;i++){if(t[j]<g[k]){m--;k++;tj-=200;}else if(t[j]>g[k]){j++;k++;tj+=200;}else{while(t[m]>g[n]){ tj+=200; m--; n--;}if(t[m]==g[k])break;else{tj-=200;m--;k++;}}}