[SCOI 2008] 奖励关
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1076
[算法]
f[i][S]表示当前第i次抛出宝物,目前集合为S,所能获得的最高分值
dp即可
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 110 const int MAXS = 1 << 15; int i,j,k,n,x,s; int S[MAXN],c[MAXN]; double f[MAXN][MAXS]; inline double dp(int now,int s) { int i; if (f[now][s] != -1) return f[now][s]; if (now == k) { f[now][s] = 0; for (i = 0; i < n; i++) { if ((S[i] & s) == S[i] && c[i] > 0) f[now][s] += c[i]; } f[now][s] /= n; } else { f[now][s] = 0; for (i = 0; i < n; i++) { if ((S[i] & s) == S[i]) f[now][s] += max(dp(now + 1,s),dp(now + 1,s | (1 << i)) + c[i]); else f[now][s] += dp(now + 1,s); } f[now][s] /= n; } return f[now][s]; } int main() { scanf("%d%d",&k,&n); for (i = 0; i < n; i++) { scanf("%d",&c[i]); s = 0; while (scanf("%d",&x) && x) s |= (1 << (x - 1)); S[i] = s; } for (i = 1; i <= k; i++) { for (j = 0; j < MAXS; j++) { f[i][j] = -1; } } printf("%.6lf\n",dp(1,0)); return 0; }