Codeforces 744C Hongcow Buys a Deck of Cards 状压dp (看题解)

Hongcow Buys a Deck of Cards

啊啊啊, 为什么我连这种垃圾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\n", ans);
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/10489825.html