AC Challenge - 计蒜客

ps:有写状压的感觉,但还是有些地方没想明白。一定要处理掉那些不合法的状态转移

const int N = 2000000;

int n;
int a[30], b[30];
vector<int> s[30];

LL dp[N];

inline void upd(LL &x, LL y) { (x < y) && (x = y); }

int main()
{
    sc(n);
    Rep(i, 1, n) {
        sc(a[i]), sc(b[i]);
        int t, u;
        sc(t);
        Rep(j, 1, t) sc(u), s[i].pb(u);
    }

    Rep(i, 0, (1 << n) - 1) {
        if (!dp[i] && i) continue;  // 因为当前的集合一定是在先前某个集合转移过来的
        rep(j, 0, n) if (!((1 << j) & i)) {
            bool flag = false;
            for (auto v : s[j + 1]) if (!((1 << (v - 1)) & i)) {
                flag = true;
                break;
            }
            if (!flag) {
                upd(dp[i | (1 << j)], dp[i] + 1ll * (__builtin_popcount(i) + 1) * a[j + 1] + b[j + 1]);
            }
        }
    }

    pr(dp[(1 << n) - 1]);
    return 0;
}

 

posted @ 2018-09-09 00:36  天之道,利而不害  阅读(145)  评论(0编辑  收藏  举报