啊啊啊, 为什么我连这种垃圾dp都写不出来。。 不是应该10分钟就该秒掉的题吗。。
从dp想到暴力然后gg, 没有想到把省下的红色开成一维。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 16; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); int n; int c[N], r[N], b[N], R, B; char s[10]; int dp[1 << N][125]; int Sr[1 << N], Sb[1 << N]; int main() { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%s%d%d", s, &r[i], &b[i]); if(s[0] == 'R') c[i] = 0; else c[i] = 1; R += r[i]; B += b[i]; } for(int S = 0; S < (1 << n); S++) { for(int i = 0; i < n; i++) if(S >> i & 1) Sr[S] += !c[i], Sb[S] += c[i]; } int ans = inf; memset(dp, -1, sizeof(dp)); dp[0][0] = 0; for(int S = 0; S < (1 << n); S++) { for(int i = 0; i <= 120; i++) { if(dp[S][i] == -1) continue; for(int j = 0; j < n; j++) { if(S >> j & 1) continue; dp[S | (1 << j)][i + min(r[j], Sr[S])] = max(dp[S | (1 << j)][i + min(r[j], Sr[S])], dp[S][i] + min(b[j], Sb[S])); } } if(S == (1 << n) - 1) { for(int i = 0; i <= 120; i++) { if(dp[S][i] == -1) continue; ans = min(ans, max(R - i, B - dp[S][i]) + n); } } } printf("%d ", ans); return 0; } /* */