bzoj 4008 亚瑟王 期望概率dp

来源:互联网 发布:prize软件破解版 编辑:程序博客网 时间:2024/06/08 13:29
对于这种看起来就比较傻逼麻烦的题,最关键的就是想怎么巧妙的设置状态数组,使转移尽可能的简洁。
一开始我想的是f[i][j]表示到第j轮第i张牌还没有被选的概率,后来发现转移起来特别坑爹,还会有重的或漏的情况。
于是改变想法:
f[i][j]表示考虑到前i张牌,还剩j轮的概率

转移也就简单了,下一张牌有两种可能,选或不选:

f[i+1][j]=f[i][j]*(1-p[i+1])^j 

f[i+1][j-1]=f[i][j]*(1-(1-p[i+1])^j)

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int n,r;double po[225][140],p[225],k[225],f[225][140],ans;int main(){register int i,j,T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&r);for(i=1;i<=n;i++)scanf("%lf%lf",&p[i],&k[i]);for(i=1;i<=n;i++){po[i][0]=1;for(j=1;j<=r;j++)po[i][j]=po[i][j-1]*(1-p[i]);}memset(f,0,sizeof(f));f[0][r]=1; ans=0;for(i=1;i<=n;i++){for(j=0;j<=r;j++){f[i][j]+=f[i-1][j]*po[i][j];f[i][j]+=f[i-1][j+1]*(1-po[i][j+1]);ans+=f[i-1][j+1]*(1-po[i][j+1])*k[i];}}printf("%0.10lf\n",ans);}return 0;}


原创粉丝点击