田忌赛马 贪心 注意细节

http://poj.org/problem?id=2287

田忌赛马

题意:给田忌 和 国王 各自n匹马

比赛n轮 每匹马只能比一场  赢的一方得200 平得0

田忌最多赢多少

思路

贪心:局部最优------》》全局最优

先排序 大到小

然后ti  ki 分别指向田忌 国王当前(即还没比)最大速度那匹马

tj  kj   各自。。。。最小速度

1)田最快 > 国王最快 -----------田肯定赢  

注意:是否拿田最快  打  国王最快    我当时认为最贪心应该看看后面还有没有也能 打过  国王最快的  有就拿那匹

分析:田  A B C D

         国王 K F J

现在会不会存在一种情况  B能打过K 但不能打过F  而A能打过F? 如果存在那就证明我上面的猜想正确 不能直接用田最快 打 王最快

A >= B   K>=F   如果B打过K 必然B就能打过F 所以不存在

所以答案应该 田最快 打 王最快 

2)田最快 < 国王最快 -----------田肯定输

         直接拿田当前最慢的 和  王最快的比

3)田最快 ==国王最快

       3.1)  如果田最慢  > 王最慢  ----田赢

                    田最慢  打 王最慢

        3.2)  如果田最慢  == 王最慢  ----田可能输 可能平

                既然赢不了 那就用田最慢  耗掉 王的最快吧

                输:田最慢   < 王最快

                平:田最慢   == 王最快(可能当前只剩1匹 最快最慢都是一匹 那不就有可能相等了)

#include<iostream>
#include<cstring>
#include<cmath>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<functional>

using namespace std;
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define LL long long
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
//#define mp make_pair
#define pb push_back
#define ULL unsigned LL
#define mem(a, b) memset(a, b, sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);

const int maxn = 1000 + 100;
int tian[maxn], king[maxn];
int cmp(int a, int b){
	return a > b;
}

int main(){
	int n;
	while (~scanf("%d", &n) && n){
		for (int i = 1; i <= n; ++i) cin >> tian[i];
		for (int i = 1; i <= n; ++i) cin >> king[i];

		sort(tian + 1, tian + n + 1, cmp);
		sort(king + 1, king + n + 1, cmp);

		int ans = 0;
		int cnt = 0;
		int ti, tj, ki, kj;
		ti = ki = 1, tj = kj = n;
		while (/*ti <= tj*/cnt < n){
			cnt++;
			//田最快  > 王最快
			//田赢200
			if (tian[ti] > king[ki]){
				ans += 200;
				ti++, ki++;
			}
			//田最快  == 王最快
			else if (tian[ti] == king[ki]){
				//田最慢  > 王最慢
				//田赢200
				if (tian[tj] > king[kj]){
					ans += 200;
					tj--, kj--;
				}
				//田最慢  <= 王最慢  田慢 打  王快 
				//田肯定输
				else{
					//为什么是田最慢 < 王最快  
					if (tian[tj] < king[ki])
						ans -= 200;
					tj--, ki++;
				}

				////田最慢  < 王最慢  田慢 打  王快  
				////田输
				//else if (tian[tj] < king[kj]){
				//	tj--,ki++;
				//	ans -= 200;
				//}
				////平局
				//else {
				//	tj--,ki++;
				//}
			}
			//田快  < 王快  拿田慢 比  王快
			//田输
			else{
				tj--, ki++;
				ans -= 200;
			}
		}

		printf("%d\n", ans);
	}
}

猜你喜欢

转载自blog.csdn.net/liangnimahanwei/article/details/82858814