題目鏈接
題意:有n個題目,每分鐘可以做一個題目,做一些特點題目之前要把規定的題目做了才能做,每個題目能做的貢獻是 T * a + b
T是做這個題目的時間。
題解:這題轉移簡單,就是預處理有些麻煩。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = (1 << 21);
ll a[23], b[23];
ll dp[N], pre[N];
int t[23], F[23], sta[N];
bool cmp(int c, int d){
return c > d;
}
int main()
{
int n, mx, cnt;
cin>>n;
mx = 1 << n;
for(int i = 0; i < n; ++i){
cin>>a[i]>>b[i]>>cnt;
for(int j = 0; j < cnt; ++j) cin>>t[j];
sort(t, t + cnt, cmp);
cnt--;
for(int j = n; j >= 1; --j){
if(cnt >= 0 && t[cnt] == j){
cnt--;
F[i] = (F[i]<<1) + 1;
}else F[i] = F[i]<<1;
}
}
for(int i = 0; i < mx; ++i){
int flag = 1;
for(int j = 0; j < n; ++j)
if((i&(1<<j)) && (i & F[j])!= F[j]) flag = 0;
sta[i] = flag;
int tmp = i;
while(tmp){
if(tmp%2) pre[i]++;
tmp/=2;
}
}
for(int i = 0; i < mx; ++i)
for(int j = 0; j < n; ++j)
if(((1<<j)&i)==0 && (i & F[j]) == F[j] && sta[i])
dp[i^(1<<j)] = max(dp[i^(1<<j)], dp[i] + a[j]*pre[i^(1<<j)]+b[j]);
printf("%lld\n", dp[mx - 1]);
}