BZOJ 1076: [SCOI2008]奖励关 [DP 期望 状压]
2017-03-05 16:26
495 查看
传送门
题意:$n$种宝物,出现$k$次每次一种,每种宝物有价值和吃掉它之前必须要吃掉的宝物的集合,求采取最优策略的期望最大价值
1<=k<=100,1<=n<=15,分值为[-10^6,10^6]内的整数。
看到$n$应该想到状压....
$f[i][s]$表示前$i$次已经吃掉的集合为$s$的期望最大值
然而正推的话,答案是谁呢?
所以倒推,表示这个状态到结束得到的期望最大值
转移枚举出现的宝物,最后乘上概率$\frac{1}{n}$
题意:$n$种宝物,出现$k$次每次一种,每种宝物有价值和吃掉它之前必须要吃掉的宝物的集合,求采取最优策略的期望最大价值
1<=k<=100,1<=n<=15,分值为[-10^6,10^6]内的整数。
看到$n$应该想到状压....
$f[i][s]$表示前$i$次已经吃掉的集合为$s$的期望最大值
然而正推的话,答案是谁呢?
所以倒推,表示这个状态到结束得到的期望最大值
转移枚举出现的宝物,最后乘上概率$\frac{1}{n}$
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N=105,S=1<<15; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int m,n,val ,need ; double f [S]; int main(){ freopen("in","r",stdin); m=read();n=read(); for(int i=0;i<n;i++){ val[i]=read();int x=read(); while(x) need[i]|=(1<<(x-1)),x=read(); } int All=1<<n; for(int i=m;i>=1;i--) for(int s=0;s<All;s++){ for(int j=0;j<n;j++){ if((s&need[j])==need[j]) f[i][s]+=max(f[i+1][s],f[i+1][s|(1<<j)]+val[j]); else f[i][s]+=f[i+1][s]; } f[i][s]/=n; } printf("%.6lf",f[1][0]); }
相关文章推荐
- 【BZOJ1076】【SCOI2008】奖励关(DP、期望、状压)
- bzoj1076 [SCOI2008]奖励关 状压+期望dp
- BZOJ 1076 SCOI2008 奖励关 期望状压DP
- BZOJ 1076: [SCOI2008]奖励关 状压,期望DP
- BZOJ 1076 [SCOI2008]奖励关 状压+期望DP 题解
- bzoj 1076: [SCOI2008]奖励关 (期望dp)
- 【BZOJ 1076】 [SCOI2008]奖励关 期望dp
- bzoj 1076: [SCOI2008]奖励关 期望dp+状态压缩
- [bzoj1076][SCOI2008]奖励关 状压DP
- BZOJ_1076_[SCOI2008]奖励关_状压DP
- 【BZOJ1076】【SCOI2008】奖励关(期望+状压dp)
- 【bzoj1076】【SCOI2008】【奖励关】期望最优值dp
- 【bzoj1076】[SCOI2008]奖励关 状压DP
- [BZOJ1076][SCOI2008]奖励关(状压DP)
- [BZOJ1076][SCOI2008]奖励关 状压dp
- bzoj1076: [SCOI2008]奖励关(期望dp+状压dp)
- 【BZOJ1076】【SCOI2008】奖励关&【BZOJ4318】OSU!()期望dp&【洛谷1850】换教室
- 【BZOJ1076】[SCOI2008]奖励关【期望DP】【状压DP】
- 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp
- [BZOJ 1076][SCOI2008]奖励关:状压DP