2018南京網路賽 NJ_E
阿新 • • 發佈:2018-12-09
#include <bits/stdc++.h> using namespace std; int bit[22]; int a[22]; int b[22]; int state[22]; long long dp[1<<20]; int numbit[1<<20]; const long long INF = 1000000000000000LL; int main() { bit[0] = 1; for (int i = 1; i < 22; i++) bit[i] = bit[i-1]<<1; //bit[i] = pow(2,i); numbit[0] = 0; for (int i = 1; i < bit[20]; i++) { numbit[i] = 1 + numbit[i&(i-1)]; } int n; while(scanf("%d", &n) == 1) { for (int i = 0; i < n; i++) { scanf("%d%d", &a[i], &b[i]); int s; scanf("%d", &s); int tmp = 0; state[i] = 0; while (s--) { scanf("%d", &tmp); state[i] |= bit[tmp-1]; //2進位制位的1表示第1題需要的前題(位置==題號) } } dp[0] = 0; for (int i = 1; i < bit[n]; i++)dp[i] = -INF; long long ans = 0; for (int i = 0; i < bit[n]; i++) { if (dp[i] == -INF)continue; ans = max(ans, dp[i]); for (int j = 0; j < n; j++) { if (i & bit[j])continue; //做過的題跳過 if ((i&state[j]) != state[j])continue;// 對於沒做過的題,若滿足其所有前題,則可以嘗試做或不做 注意所有位運算操作都比一般運算優先順序低,若要先進行位運算必須加()!!! dp[i|bit[j]] = max(dp[i|bit[j]],dp[i] + (long long)(numbit[i]+1)*a[j] + b[j]); //做bit[j]二進位制1位置的題,保留最佳狀態 } } cout<<ans<<endl; } return 0; }