Card game (Standard IO)
Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits
Time to Submit: 01:59:17
Description
Small X in order to show their superb skills of the game, one day happily find a small Y playing a card game. Each card has a type (attack or defense) and two power value information.
Small cards Y n-card, the small card X has the m. X known small cards that are all type of attack.
Each round of the game by the small X operating, first select a not used the card from his hand X. If you do not have the small Y card, the damage to the power of the value of X, otherwise little X to Y is selected from small hand a card Y. If Y is attacking (power only when the value of X is not less than the value of Y power optional), disappeared after the end of the current round of Y, Y small the damage is the difference between the power value of the power value of X and Y; if Y defensive type (power only when the value of X is greater than Y force value selectable), disappeared after the end of the current round of Y, Y does not hurt small.
X may end his small operation (cards do not have to run out) at any time. Smart hope you help him operate so that the total damage small Y at risk.
Input
First line of input contains two integers n and m.
The next n lines contains a string and an integer, respectively, of a small Y type of card ( "ATK" represents the attack, "DEF" represents defensive) and strength values.
Next m lines contains an integer that represents the power of a card value of X is small.
Output
Output line contains an integer representing the maximum total damage suffered by small Y.
Sample Input
Input 1:
2 3
ATK 2000
DEF 1700
2500
2500
2500
Input 2:
3 4
ATK 10
ATK 100
ATK 1000
1
11
101
1001
Sample Output
Output 1:
3000
Sample Description [1]
The first round, small X to choose their first cards and small Y's second card, small Y's second card disappear.
The second round, small X to choose their second card and a small Y of the first card, the small card Y of the first to disappear, while being 500 damage.
The third round, small X to choose their third card, then the hands of small Y has no cards, by 2500 damage.
X small end of the game, the small Y 3000 were subject to damage.
Output 2:
992
Sample Description [2]
The first round, small X to choose their third cards and small Y of the first card, the small card Y of the first to disappear, while being 91 points of damage.
The second round, small X to choose their own cards and fourth small Y's second card, the small card Y's second disappearance, at the same time by 901 points of damage.
X small end of the game, by a total of 992 small Y damage.
Data Constraint
Half of all sizes are small data satisfy Y only attack cards.
For 30% of the data, 1≤ n, m ≤ 6.
For 60% of the data, 1≤ n, m ≤10 ^ 3 .
To 100% of the data, 1≤ n, m ≤10 ^ 5 , the power values are non-negative integers not more than 10 ^ 6.
A violent search (30)
This problem can currently guarantee the right looks like the search, but it will TLE's.
#include<bits/stdc++.h> using namespace std; inline int poread() { char c = 0; int res = 0; while(!isdigit(c = getchar())); do { res = res * 10 + c - 48; } while(isdigit(c = getchar())); return res; } const int MAXN = 1e5 + 5; int n,m; struct node { bool isstack; int force; }Y[MAXN]; int X[MAXN]; bool v_Y[MAXN],v_X[MAXN]; int ans; void dfs(int now,int cnt) { ans = max(ans,now); // cerr<<cnt<<":"<<now<<" "<<x<<" "<<y<<endl; // for(register int i = 1; i <= n; ++i) // cerr<<v_Y[i]; // cerr<<endl; // for(register int i = 1; i <= m; ++i) // cerr<<v_X[i]; // cerr<<endl; if(cnt > m ) { return; } int sum = now; if(cnt >= n) { for(register int j = 1; j <= m; ++j) { if(!v_X[j]) { sum = now; v_X[j] = true; sum += X[j]; dfs(sum, cnt + 1); v_X[j] = false; } } } else { for(register int i = 1; i <= n; ++i) { if(!v_Y[i]) { for(register int j = 1; j <= m; ++j) { if(!v_X[j]) { sum = now; if(Y[i].isstack) { if(X[j] < Y[i].force) continue; sum += (X[j] - Y[i].force); } else { if(X[j] <= Y[i].force) continue; } v_Y[i] = true, v_X[j] = true; dfs(sum,cnt + 1); v_Y[i] = false, v_X[j] = false; } } } } } } int main() { #ifdef lky233 freopen("testdata.in","r",stdin); freopen("testdata.out","w",stdout); #endif n = poread(); m = poread(); for(register int i = 1; i <= n; ++i) { char s[10]; scanf("%s",s); Y[i].force = poread(); Y[i].isstack = (s[0] == 'A'); } for(register int i = 1; i <= m; ++i) { X[i] = poread(); } dfs(0,0); cout<<ans<<endl; }
Second, the pan of greed
This greedy strategy is that, first of all for that matter, there are two strategies:
1, to attack the other's attack cards to get the end of the game after the score.
The master said: For this strategy, we will be descending order x, y from small to large, it has been attacked until the end.
For sample 2, the policy can be, and was originally A of this problem.
Hack:
March 2
Computer 599
Computer 1000
1200
600
450
Obviously if you use the above strategy, ans = 601, but 1200> 1000,600-> 599,450-> face, you will get 651 points.
2, take all the opponent's cards light, and with their own cards to play each other face direct attack.
For this strategy, it should be consumed with minimal lift off the shield to answer no contribution after use policy 1 Attack cards, and finally make up their faces.
For data pan, using the y and descending row again calculated over max embodiment taken out. (Data-oriented programming Gong)
#include<bits/stdc++.h> using namespace std; #define int long long inline int poread() { char c = 0; int res = 0; while(!isdigit(c = getchar())); do { res = res * 10 + c - 48; } while(isdigit(c = getchar())); return res; } const int MAXN = 1e5 + 7; int n,m; int ans_1,ans_2,ans_3; struct node { int x; bool isstack; void in() { char s[10]; scanf("%s",s); isstack = (s[0] == 'A'); x = poread(); } }datax[MAXN],datay[MAXN],x[MAXN],y[MAXN],tmpdata[MAXN]; bool cmp1(node a,node b)//从小到大 { return a.x < b.x; } bool cmp2(node a,node b)//从大到小 { return a.x > b.x; } void tan_1()//只打掉Attack { int tmpans_1 = 0,tmpans_2 = 0; int tmpm = 0,tmpn = 0; memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); memcpy(x,datax,sizeof(datax)); for(register int i = 1;i <= n; ++i) { if(datay[i].isstack) y[++tmpn] = datay[i]; } sort(y+1,y+tmpn+1,cmp1); sort(x+1,x+m+1,cmp2); int nn = min(tmpn,m); for(register int i = 1; i <= nn; ++i) { if(x[i].x < y[i].x) break; tmpans_1 += x[i].x - y[i].x; } sort(y+1,y+tmpn+1,cmp2); for(register int i = 1; i <= nn; ++i) { if(x[i].x < y[i].x) break; tmpans_2 += x[i].x - y[i].x; } ans_1 = max(tmpans_1,tmpans_2); } bool v[MAXN]; void tan_2() { if(n > m) { ans_2 = 0; return; } int tmpans_1 = 0,tmpans_2 = 0; memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); for(register int i = 1; i <= m; ++i) { tmpdata[i] = datax[i]; } int tmpm = 0,tmpn = 0; for(register int i = 1; i <= n; ++i) { if(!datay[i].isstack) y[++tmpn] = datay[i]; } //双指针,破盾 sort(tmpdata+1,tmpdata+m+1,cmp1); sort(y+1,y+tmpn+1,cmp1); int point1 = 1,point2 = 1,tmp_cnt = 0; while(point1 <= m && point2 <= tmpn) { // cerr<<point1<<endl; while(tmpdata[point1].x <= y[point2].x) { if(point1 > m) break; ++point1; } if(tmpdata[point1].x >the y-[Point2] .x) ++ tmp_cnt, v [Point1] = to true ; ++ Point2; ++ Point1; } // cerr << 1 << endl; // can not break all the shield, this strategy is not feasible. IF (tmp_cnt < TMPn) { ans_3 = 0 ; return ; } TMPn = TMPM = 0 ; for (Register int I = . 1 ; I <= m; ++ I) { IF (! V [I]) X [ ++ tmpm] = tmpdata[i]; } memset(y,0,sizeof(y)); for(register int i = 1; i <= n; ++i) { if(datay[i].isstack) y[++tmpn] = datay[i]; } sort(y+1,y+tmpn+1,cmp1); sort(x+1,x+tmpm+1,cmp2); int nn = min(tmpn,tmpm),mm = max(tmpn,tmpm); #ifdef lky233 for(register int i = 1; i <= tmpm; ++i) cerr << x[i].x << endl; for(register int i = 1; i <= tmpn; ++i) cerr << y[i].x << endl; #endif bool con = 1; for(register int i = 1; i <= nn; ++i) { if(x[i].x < y[i].x) { con = 0; break; } tmpans_1 += x[i].x - y[i].x; } if(con) for(register int i = nn + 1; i <= mm; ++i) { tmpans_1 += x[i].x; } con = 1; sort(y+1,y+tmpn+1,cmp2); for(register int i = 1; i <= nn; ++i) { if(x[i].x < y[i].x) { con = 0; break; } tmpans_2 += x[i].x - y[i].x; } if(con) for(register int i = nn + 1; i <= mm; ++i) { tmpans_2 += x[i].x; } ans_2 = max(tmpans_1,tmpans_2); // cerr<<tmpans_1<<' '<<tmpans_2<<endl; return; } signed main() { #ifdef lky233 freopen("testdata.in","r",stdin); freopen("testdata.out","w",stdout); #endif n = poread(); m = poread(); for(register int i = 1; i <= n; ++i) datay[i].in(); for(register int i = 1; i <= m; ++i) datax[i].x = poread(); tan_1(); tan_2(); // cerr<<ans_1<<" "<<ans_2<<endl; cout<<max(ans_1,ans_2)<<endl; return 0; }
Redundant code optimization also very much ......
Third, realize that greed is the right and then to supplement
Hack actual data is considered to be the policy 2.
Strategy 2 Fixed: rip each other's shield, after one's own sigma Attack - other sigma Attack;
Strategy 1 Proof: use a smaller number of attacks on each other's number, will reduce the contribution.
Strategy 2: As long as the other party can be broken shield, attack order is already not affect the final answer ......
Code Gugu Gu away, dormitory.