容易想到需要思考能否把對面全部殺死,如果能,那麼。。。不能,則一定不會去殺防守的。
貪心的思路大致有了方向,然後,不能的話,要怎麼做呢?策略是用我這邊最大的比對手最小的。證明如下,假設我手上的任意一張牌x1和最大的牌x2(x1 < x2)和對面的任意一張牌y2和最小的牌(y1 < y2),滿足x2 > y2(否則一個都殺不死),如果y1 < y2 < x1 < x2,則用最大的去殺最小的沒有問題,因為x中任意一張牌都比y大,如果y1 < x1 < y2 < x2,用最大的殺最小的總傷害是,x2-y1,不這樣做傷害是x2-y2+x1-y1,前式減後式得,y2-x1,這個值小於0,所以貪心策略是正確的。
然後考慮能把對面全部殺死,還是貪心策略,對於對手防守狀態的牌,我就用恰比它大的殺死它,剩下的傷害計算與安排的順序無關,結果是sum of strength of Ciel's remain card) — (sum of strength of Jiro's remain card).
#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <string>#include <vector>typedef long long LL;using namespace std;const int maxn = 100 + 5;vector<int> A,D;int att[maxn],vis[maxn];string s;int main(){ int n,m; while(cin >> n >> m){ A.clear(); D.clear(); for(int i = 0;i < n;i++){ int tem; cin >> s >> tem; if(s[0] == 'A') A.push_back(tem); else D.push_back(tem); } for(int i = 0;i < m;i++) cin >> att[i]; sort(A.begin(),A.end()); sort(D.begin(),D.end()); sort(att,att+m); int ans = 0; int p = 0,cnt = 0; memset(vis,0,sizeof(vis)); for(int i = 0;i < D.size() && p < m;){ if(att[p] > D[i]){ vis[p] = 1; p++; i++; cnt++; } else p++; } if(cnt == D.size()){ int tem = 0,p = 0,cnt = 0; for(int i = 0;i < A.size() && p < m;){ if(vis[p] == 0 && att[p] >= A[i]){ tem += att[p] - A[i]; vis[p] = 1; i++; p++; cnt++; } else p++; } if(cnt != A.size()){ ans = 0; } else{ for(int i = 0;i < m;i++){ if(vis[i] == 0) { tem += att[i]; } } ans = tem; } } int tem = 0; p = m - 1; for(int i = 0;i < A.size() && p >= 0;){ if(att[p] > A[i]){ tem += att[p] - A[i]; p--; i++; } else break; } ans = max(ans,tem); cout << ans << endl; } return 0;}