Luogu P2473 奖励关 (状压DP, 期望)
https://www.luogu.com.cn/problem/P2473
- 倒推
- f[i][S] 表示1到i-1关拿的物品集合为S,从i到最后的期望
- 不知道下一关出现的是哪种物品,所以当前的期望是下一步所有情况的最优决策乘 1/k。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
//#define int long long
const int N = 2e5 + 5;
const int M = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double PI = acos(-1.0);
int p[16], a[16];
double f[105][1 << 16];
int main () {
IOS
int n, k; cin >> n >> k;
for ( int i = 0; i < k; ++ i ) {
cin >> a[i]; int x;
while( cin >> x ) {
if( !x ) break;
-- x; p[i] |= ( 1 << x );
}
}
for ( int i = n; i >= 1; -- i) {
for ( int S = 0; S < 1 << k; ++ S ) {
for ( int j = 0; j < k; ++ j ) {
if( (S & p[j]) == p[j] ) {
f[i][S] += max( f[i + 1][S], f[i + 1][S | (1 << j)] + a[j]);
} else {
f[i][S] += f[i + 1][S];
}
}
f[i][S] /= k;
}
}
printf("%.6lf\n", f[1][0]);
return 0;
}