容易想到需要思考能否把对面全部杀死,如果能,那么。。。不能,则一定不会去杀防守的。
贪心的思路大致有了方向,然后,不能的话,要怎么做呢?策略是用我这边最大的比对手最小的。证明如下,假设我手上的任意一张牌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;
}