Codeforces 377(#222 Div1) C. Captains Mode
問題
n個の石を二人が取り合う。i番目の石の得点はa[i]点。
二人が取れる行動は予め決まっていて、第iターン目には、
プレイヤーt[i]が、
s[i] = 'b'なら場の石を一個捨てる(両プレイヤーに点数は入らない)、
s[i] = 'p'なら場の石を自分のものにする(自分にa[i]点が入る)
両者が最善を尽くして石を選ぶとき、先手の得点 - 後手の得点の最大値を求めよ。
制約条件
n≦100
m≦min(n, 20)
方針
得点が大きい順にm個の石だけが関係するので、その石だけ考える。
すると石は20個になるのでmin-maxがbitDPできる。
ソースコード
int n, a[100], m, t[20]; char in[20]; int dp[1 << 20]; int rec(int mask, int c){ int &res = dp[mask]; if(res < inf) return res; if(c == m) return res = 0; if(t[c] == 1) res = -inf; rep(i, m) if(!(mask & 1 << i)){ if(t[c] == 1) res = max(res, rec(mask ^ 1 << i, c + 1) + (in[c] == 'b' ? 0 : a[i])); if(t[c] == 2) res = min(res, rec(mask ^ 1 << i, c + 1) - (in[c] == 'b' ? 0 : a[i])); } return res; } int main(){ rep(i, 1 << 20) dp[i] = inf; cin >> n; rep(i, n) cin >> a[i]; cin >> m; rep(i, m) cin >> in[i] >> t[i]; sort(a, a + n, greater<int>()); cout << rec(0, 0) << endl; return 0; }