bzoj 1076 状态压缩最优期望

题意:

你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关。在这个奖励关里,系统将依次随 机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃)。 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立。也就是说,即使前k-1次系统都抛出宝物1(这种情况是有可能出现的,尽管概率非常 小),第k次抛出各个宝物的概率依然均为1/n。 获取第i种宝物将得到Pi分,但并不是每种宝物都是可以随意获取的。第i种宝物有一个前提宝物集合Si。只有当Si中所有宝物都至少吃过一次,才能吃第i 种宝物(如果系统抛出了一个目前不能吃的宝物,相当于白白的损失了一次机会)。注意,Pi可以是负数,但如果它是很多高分宝物的前提,损失短期利益而吃掉 这个负分宝物将获得更大的长期利益。 假设你采取最优策略,平均情况你一共能在奖励关得到多少分值?

dp[i][s] 还剩i次掉落机会,前k-i次已经选择了s的物品,那么接下来最优期望得多少分.

有种倒推的感觉,状态中保存了已经做的决策对该后续决策有影响的信息,相当与提前假设,然后根据未来的不同情况选择当前的最有决策.

 1 /**************************************************************
 2     Problem: 1076
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:1144 ms
 7     Memory:26660 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #define max(a,b) ((a)>(b)?(a):(b))
12 #define K 101
13 #define N 15
14
15 int n, k;
16 int a[N], r[N], bound;
17 double dp[K][1<<N];
18
19 int main() {
20     scanf( "%d%d", &k, &n );
21     for( int i=0,p; i<n; i++ ) {
22         scanf( "%d", a+i );
23         while(1) {
24             scanf( "%d", &p );
25             if( p==0 ) break;
26             r[i] |= 1<<(p-1);
27         }
28     }
29     bound = (1<<n)-1;
30     for( int i=1; i<=k; i++ ) {
31         for( int s=0; s<=bound; s++ ) {
32             dp[i][s] = 0.0;
33             for( int j=0; j<n; j++ ) {
34                 if( (s & r[j]) == r[j] ) {
35                     double v1 = a[j]+dp[i-1][s|(1<<j)];
36                     double v2 = dp[i-1][s];
37                     dp[i][s] += max( v1, v2 );
38                 } else {
39                     dp[i][s] += dp[i-1][s];
40                 }
41             }
42             dp[i][s] /= n;
43         }
44     }
45     printf( "%.6lf\n", dp[k][0] );
46 }

时间: 2024-08-03 13:05:47

bzoj 1076 状态压缩最优期望的相关文章

BZOJ 1087状态压缩DP

状态压缩DP真心不会写,参考了别人的写法. 先预处理出合理状态, 我们用二进制表示可以放棋子的状态,DP[I][J][K]:表示现在处理到第I行,J:表示第I行的状态,K表示现在为止一共放的棋子数量. #include<stdio.h> #include<iostream> #define N 1111 using namespace std; typedef long long ll; int num,n,m; ll dp[11][1<<11][90]; int hh

BZOJ 1076 奖励关(状压期望DP)

当前得分期望=(上一轮得分期望+这一轮得分)/m dp[i,j]:第i轮拿的物品方案为j的最优得分期望 如果我们正着去做,会出现从不合法状态(比如前i个根本无法达到j这种方案),所以从后向前推 如果当前方案j里具备了取k这个物品的条件 那么dp[i,j]+=max{dp[i+1,j],dp[i+1,j  or  1<<(k?1)]+x[k]} 否则dp[i,j]+=dp[i+1,j] #include<cstdio> #include<iostream> using n

[BZOJ 1076][SCOI2008]奖励关(期望+状压Dp)

Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃).  宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立.也就是说,即使前k-1次系统都抛出宝物1( 这种情况是有可能出现的,尽管概率非常小),第k次抛出各个宝物的概率依然均为1/n. 获取第i种宝物将得到Pi 分,但并不是每种宝物都是可以随意获取的.第i种宝物有一个前

HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由于得到每张卡片的状态不知道,所以用状态压缩,dp[i] 表示这个状态时,要全部收齐卡片的期望. 由于有可能是什么也没有,所以我们要特殊判断一下.然后就和剩下的就简单了. 另一个方法就是状态压缩+容斥,同样每个状态表示收集的状态,由于每张卡都是独立,所以,每个卡片的期望就是1.0/p,然后要做的就是要去重,既然

BZOJ 2734 集合选数(状态压缩DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2734 题意:给出一个由1到n的数字组成的集合.定义合法子集为若x在子集中则2x.3x均不能在子集中.求有多少个合法的子集. 思路: 1   3    9 2   6    12 4   12   36 对于上面的矩阵,我们发现就等价于不选相邻数字的方案数.因此枚举每个还没有用到的数字,建立以该数字为左上角的矩阵.接着就是状态压缩DP. int a[N][N]; i64 f[2][1<<

HDU4336——期望+状态压缩DP——Card Collector

http://acm.hdu.edu.cn/showproblem.php?pid=4336 转自http://www.cnblogs.com/zhj5chengfeng/archive/2013/03/02/2939601.html 做法分析 由于卡片最多只有 20 种,使用状态压缩,用 0 表示这种卡片没有收集到, 1 表示这种卡片收集到了 令:f[s] 表示已经集齐的卡片种类的状态的情况下,收集完所有卡片需要买东西次数的期望 买一次东西,包装袋中可能: 1. 没有卡片 2. 卡片是已经收集

hdu 4336 Card Collector(期望 dp 状态压缩)

Problem Description In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, for example, if you collect all the 108 people in the famous novel Water Margin, you will win an amazing award. As a smart boy, you

状态压缩dp 最优配对问题

在空间中的n(n为偶数)个点,配成n对,然后使得每一个点在一个点对中.所有的点对的距离之和最小 #include <cstdio> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <climits> #include <cstring> #include <cmath> #include &l

bzoj 1076: [SCOI2008] 奖励关 题解

[原题] 1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 684  Solved: 403 [Submit][Status] Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃). 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立.