bzoj1076: [SCOI2008]奖励关

题目链接

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;
}
posted @ 2018-04-29 19:27  zzzzx  阅读(99)  评论(0编辑  收藏  举报