UVa LA 3266 - Tian Ji -- The Horse Racing 貪心,不只處理一端,也處理另一端以理清局面 難度: 2
阿新 • • 發佈:2019-04-09
優先 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