1. 程式人生 > >UVa LA 3266 - Tian Ji -- The Horse Racing 貪心,不只處理一端,也處理另一端以理清局面 難度: 2

UVa LA 3266 - Tian Ji -- The Horse Racing 貪心,不只處理一端,也處理另一端以理清局面 難度: 2

優先 i++ pen repos repo esp 解決 無法 pos

題目

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1267


題意

田忌賽馬,問最多能贏到多少錢?每局200元

思路

明顯,把田忌的賽馬排列一下,從速度高到低,齊王的也從高到低排列,當前田忌最高的賽馬無法處理齊王最高的賽馬,則換成田忌最慢的賽馬去碰瓷。

難在如何處理平局-也就是速度相同的賽馬。

有的時候本可以平局,但是最好先認輸一局-換用目前最慢的賽馬去碰瓷一下,然後當前這匹賽馬與接下來比它弱的賽馬比試,這樣做勝一局負一局,收益為0,與直接平局是相同的。但是優點在於額外用田忌的駑馬解決了一匹齊王的好馬。

那麽,何時直接平局,何時解決額外的馬呢?

不妨看看目前的駑馬,如果當前自己最慢的馬還能解決齊王的最慢馬,那麽優先讓這個對局發生。直到自己最慢的馬無法解決齊王最慢的馬,此時用這匹駑馬來額外解決齊王的快馬。

感想

1. 一開始只想到越高越好,從高到低直接處理,沒有考慮到當前自己最慢的馬還能解決齊王的最慢馬這種情況,導致沒法選擇何時應該主動放棄平局。

2. 之後用了DP,太慢

3. 不只處理一端,也處理另一端以理清局面

代碼

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1e3 + 3;
typedef pair<int, int> Pair;
int a[MAXN];
int b[MAXN];
int n;
int main() {
	int T;
	//scanf("%d", &T);
	freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\input.txt", "r", stdin);
	//freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\output.txt", "w", stdout);
	for (int ti = 1; scanf("%d", &n) == 1 && n; ti++) {
		for (int i = 0; i < n; i++) {
			scanf("%d", a + i);
		}
		sort(a, a + n);
		for (int i = 0; i < n; i++) {
			scanf("%d", b + i);
		}
		sort(b, b + n);
		int ans = 0;
		for (int ai = n - 1, astart = 0, bi = n - 1, bstart = 0; ai >= astart && bi >= bstart; ) {
			while (bi >= 0 && a[ai] < b[bi]) {
				bi--;
				ans--;
				astart++;
			}
			if (bi >= 0) {
				if (a[ai] > b[bi]) {
					ans++;
					bi--;
					ai--;
				}
				else {
					while (ai >= astart && bi >= bstart && a[astart] > b[bstart]) {
						ans++;
						astart++;
						bstart++;
					}
					if (ai >= astart && bi >= bstart && a[astart] < b[bi]) {
						astart++;
						bi--;
						ans--;
					}
					else {
						break;
					}
				}
			}
		}
		printf("%d\n", ans * 200);
	}
	return 0;
}

  

UVa LA 3266 - Tian Ji -- The Horse Racing 貪心,不只處理一端,也處理另一端以理清局面 難度: 2