bzoj1076: [SCOI2008]奖励关
题目链接
题解
dp[i][j]表示第i个物品时,拿取状况为j的最优解的期望
正推是很难的,因为dp[i][j]不一定存在
考虑倒推,则不会影响,因为不存在的也用不到,最后dp[1][0]一定是可行的
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 17;
double dp[107][(1 << maxn) + 7];
int K,n;
int v[maxn],can[maxn];
int main() {
scanf("%d%d",&K,&n);
for(int tmp,i = 0;i < n;++ i) {
scanf("%d",v + i);
while(scanf("%d",&tmp) == 1 && tmp) can[i] |= (1 << tmp - 1);
}
for(int i = K;i;-- i) {
for(int j = 0;j < (1 << n);++ j) {
for(int k = 0;k < n;++ k) {
if((can[k] & j) == can[k])
dp[i][j] += std::max(dp[i + 1][j],dp[i + 1][j | (1 << k)] + v[k]);
else dp[i][j] += dp[i + 1][j];
}
dp[i][j] /= (1.0 * n) ;
}
}
printf("%lf\n",dp[1][0]);
return 0;
}