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; }