题目链接
状压DP
DP[S]表示S中所有的问题都解决的可以获得的最大权值
代码
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep(i, l, r) for(unsigned int i = l; i < r; i++)
#define per(i, r, l) for(unsigned int i = r; i >= l; i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>pii;
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
typedef gp_hash_table <ull, bool> HASH;
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
typedef tree<pii, null_type, less< pii >, rb_tree_tag,tree_order_statistics_node_update> rbtree;
#include <ext/rope>
using namespace __gnu_cxx;
const int N = (int) 1e5 + 11;
const int M = (int) 1e6 + 11;
const int MOD = (int) 1e9 + 7;
const double EPS = (double) 1e-9;
const double PI = (double)acos(-1.0);
const int INF = (int) 0x3f3f3f3f;
const ll INFF = (ll) 0x3f3f3f3f3f3f3f3f;
ll add(ll x, ll y){return (x += y) >= MOD ? x - MOD : x;}
ll sub(ll x, ll y){return (x -= y) < 0 ? x + MOD : x;}
void read(int &x){
char ch = getchar(); x = 0;
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
}
/*-----------------------------------------------------------------------------------*/
pii info[100];
vector<int>ve[100];
ll dp[(1 << 21)];
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n; cin >> n;
rep(i, 0, n){
static int a, b;
scanf("%d%d", &a, &b); info[i] = make_pair(a, b);
static int cnt; scanf("%d", &cnt);
while(cnt--){
static int c; scanf("%d", &c);
ve[i].push_back(c - 1);
}
}
rep(S, 1, (1 << n)){
bool flag = 1;
int cnt = 0;
rep(j, 0, n){
if(S >> j & 1){
rep(k, 0, ve[j].size()){
int v = ve[j][k];
if(!(S >> v & 1)) {flag = 0; break;}
}
cnt++;
}
if(!flag) break;
}
if(!flag) continue;
rep(j, 0, n){
if(S >> j & 1){
dp[S] = max(dp[S], dp[S ^ (1 << j)] + info[j].first * 1ll * cnt + info[j].second);
}
}
}
printf("%lld\n", dp[(1 << n) - 1]);
return 0;
}