题目链接:https://nanti.jisuanke.com/t/30994
题意:有n道题,做第i道题首先得做Si道题(p1,p2,...,psi),做一道题需要一分钟,在t时刻完成第i道题可以获得t×ai+bi分数
求最大值
思路:首先看数据就暗示了状压,1 << i表示第i道题,于是可以连一条 到i的有向边,然后记忆化搜索就好
#include<bits/stdc++.h>
//#define DEBUG
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const int maxn = 25;
const ll mod = 1e9 + 7;
const double pi = acos(-1);
int n, m, cnt;
int a[maxn];
int b[maxn];
ll ans;
map<int, ll> check[maxn];
vector<int> P[1 << 21];
set<int> S;
inline void DFS(int t, int state, ll res)
{
ans = max(ans, res);
//cout << u << " " << t << " " << state << " " << res << endl;
if(check[t][state] > res) return;
check[t][state] = res;
for(auto x: S)
{
if((state & x) == x)
{
for(auto v: P[x])
if((state & (1 << v)) == 0)
{
DFS(t + 1, state | (1 << v), res + 1LL * a[v] * t + b[v]);
}
}
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
while(cin >> n)
{
int tmp, s;
for(int i = 1; i <= n; i++)
{
cin >> a[i] >> b[i];
cin >> s;
int x = 0;
while(s--)
{
cin >> tmp;
x |= 1 << tmp;
}
P[x].push_back(i);
S.insert(x);
}
ans = 0;
DFS(1, 0, 0);
cout << ans << endl;
}
return 0;
}