$[SCOI2008]$奖励关
Posted wo-shi-zhen-de-cai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$[SCOI2008]$奖励关相关的知识,希望对你有一定的参考价值。
考虑状压(DP),显然设状态为(f[i][S])表示所取集合为(S),到第(i)轮时的期望。
然后写方程。。。
不对,有点难写。。。
仔细考虑一下,我们会发现实因为我们求的是期望,要知道一个状态从哪些状态转移过来。
但是这样设状态并不能方便的求出。
设(f[i][S])为前(i)轮所取集合为(S),第(i)到第(K)轮的答案。
倒退即可。
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int f=1,w=0;char x=0;
while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
return w*f;
}
const int N=20;
const int M=110;
int n,K,Las[N],P[N];
double f[M][1<<N],ans;
int main(){
#ifndef ONLINE_JUDGE
freopen("A.in","r",stdin);
#endif
K=read(),n=read();
for(register int i=1;i<=n;++i)
{
P[i]=read();register int x=read();
while(x) Las[i]|=(1<<(x-1)),x=read();
}
for(register int i=K;i>=1;--i)
for(register int S=0;S<(1<<n);++S)
{
for(register int j=1;j<=n;++j)
if((S|Las[j])!=S) f[i][S]+=f[i+1][S];
else f[i][S]+=max(f[i+1][S],f[i+1][S|(1<<(j-1))]+P[j]);
f[i][S]/=n;
}
printf("%.6lf",f[1][0]);
}
以上是关于$[SCOI2008]$奖励关的主要内容,如果未能解决你的问题,请参考以下文章