博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
火山喷发 计蒜客16862 NOIP模拟赛 概率DP
阅读量:6038 次
发布时间:2019-06-20

本文共 4294 字,大约阅读时间需要 14 分钟。

题目描述

输入格式

输出格式

数据范围与约定

对于 10% 的数据 N=1

对于 30% 的数据 N=2。

对于全部数据 N4,M≤120 , A_i≤50。

样例输入1

1 21

样例输出1

0.000000

样例输入2

3 152 12 2

样例输出2

0.0016840.9966320.001684

题目来源

什么?你想用DFS?复杂度可能是O(4*120!),也就大概是的复杂度。

所以,这道题很明显就是一道概率DP的题~

DP数组表示?

对于本题,不妨 f[i][j][k][v] 表示1、2、3、4种生物的生命值为i、j、k、v的概率

初始值?

很显然,对于读入的 a[1...n],可以有 f[a[1]][a[2]][a[3]][a[4]]=1 (没有读入的生命值为0)

怎么转移?

对于a[1]+a[2]+a[3]+a[4]<=m的情况,直接输出n个0.000000即可。(难道这还用问为什么?

若a[1]+a[2]+a[3]+a[4]>m,开始dp。

1 dp[a[1]][a[2]][a[3]][a[4]]=1; 2     for (register int i=a[1];i>=0;--i) 3         for (register int v=a[2];v>=0;--v) 4             for (register int k=a[3];k>=0;--k) 5                 for (register int j=a[4];j>=0;--j) 6                 { 7                     if(a[1]-i+a[2]-v+a[3]-k+a[4]-j>m) continue; 8                     register int cnt=0; 9                     if(i)++cnt; if(v)++cnt; if(k)++cnt; if(j)++cnt;10                     if(!cnt) continue;11                     double gl=1.000000/(double)cnt;12                     if(i) dp[i-1][v][k][j]+=gl*dp[i][v][k][j];13                     if(v) dp[i][v-1][k][j]+=gl*dp[i][v][k][j];14                     if(k) dp[i][v][k-1][j]+=gl*dp[i][v][k][j];15                     if(j) dp[i][v][k][j-1]+=gl*dp[i][v][k][j];16                 }

方程的含义是显而易见的。由当前状态推向下一状态,并乘以对应的概率。

如何求得答案?

举个栗子,对于一个对第一个生物生存的概率询问,我们遍历求和,sum=Σf[0][j][k][v],其中j<=a[2],k<=a[3],v<=a[4],且 a[1]+a[2]-j+a[3]-k+a[4]-v==m

这样,我们求到的sum是第一个生物死亡的概率,我们回答 1.0-sum 即可

 

附上AC代码

1 #include
2 #include
3 using namespace std; 4 template
inline void read(_T &_a) 5 { 6 char _ch=getchar();_a=0; 7 while(_ch<'0'||_ch>'9')_ch=getchar(); 8 while(_ch>='0'&&_ch<='9'){_a=(_a<<3)+(_a<<1)+_ch-'0';_ch=getchar();} 9 }10 11 const int maxn=5;12 int n,m,a[maxn];13 double dp[51][51][51][51];14 15 int main()16 {17 freopen("volcano.in","r",stdin);18 freopen("volcano.out","w",stdout);19 read(n); read(m);20 for (register int i=1;i<=n;++i) read(a[i]);21 if(m>=a[1]+a[2]+a[3]+a[4])22 {23 for (register int i=1;i<=n;++i) printf("0.000000\n");24 return 0;25 }26 dp[a[1]][a[2]][a[3]][a[4]]=1;27 for (register int i=a[1];i>=0;--i)28 for (register int v=a[2];v>=0;--v)29 for (register int k=a[3];k>=0;--k)30 for (register int j=a[4];j>=0;--j)31 {32 if(a[1]-i+a[2]-v+a[3]-k+a[4]-j>m) continue;33 register int cnt=0;34 if(i)++cnt; if(v)++cnt; if(k)++cnt; if(j)++cnt;35 if(!cnt) continue;36 double gl=1.000000/(double)cnt;37 if(i) dp[i-1][v][k][j]+=gl*dp[i][v][k][j];38 if(v) dp[i][v-1][k][j]+=gl*dp[i][v][k][j];39 if(k) dp[i][v][k-1][j]+=gl*dp[i][v][k][j];40 if(j) dp[i][v][k][j-1]+=gl*dp[i][v][k][j];41 }42 for (register int i=1;i<=n;i++)43 {44 register double ans=0;45 if (i==1)46 for (register int j=0;j<=a[2];++j)47 for (register int k=0;k<=a[3];++k)48 for (register int p=0;p<=a[4];++p)49 if (a[1]+a[2]-j+a[3]-k+a[4]-p==m)50 ans+=dp[0][j][k][p];51 if (i==2)52 for (register int j=0;j<=a[1];++j)53 for (register int k=0;k<=a[3];++k)54 for (register int p=0;p<=a[4];++p)55 if (a[1]-j+a[2]+a[3]-k+a[4]-p==m)56 ans+=dp[j][0][k][p]; 57 if (i==3)58 for (register int j=0;j<=a[1];++j)59 for (register int k=0;k<=a[2];++k)60 for (register int p=0;p<=a[4];++p)61 if (a[1]-j+a[2]-k+a[3]+a[4]-p==m)62 ans+=dp[j][k][0][p]; 63 if (i==4)64 for (register int j=0;j<=a[1];++j)65 for (register int k=0;k<=a[2];++k)66 for (register int p=0;p<=a[3];++p)67 if (a[1]-j+a[2]-k+a[3]-p+a[4]==m)68 ans+=dp[j][k][p][0]; 69 printf("%lf\n",1.000000-ans);70 }71 return 0;72 }
View Code

 

转载于:https://www.cnblogs.com/jaywang/p/7719699.html

你可能感兴趣的文章
Mac OS 批量删除.svn文件夹
查看>>
SDWebImageDecoder
查看>>
iOS 开发之设置UIButton的title
查看>>
ROCKETMQ——事务消息发送、消费示例
查看>>
oracle 锁表
查看>>
wordpress功能集成(四)改变评论框样式
查看>>
linux 下 C 编程和make的方法 ( 九、malloc 和free的使用 上)
查看>>
远程桌面发生身份验证错误,要求的函数不受支持
查看>>
Python---学习中遇到的错误
查看>>
Openldap NFS autofs configuration
查看>>
【工具使用系列】关于 MATLAB 符号运算,你需要知道的事
查看>>
java 快速排序
查看>>
hibernate id 生成策略
查看>>
百度开源高性能RPC框架 sofa-pbrpc
查看>>
js 同步代码 让程序暂停
查看>>
Linux下拷贝文件夹并过滤不想要的文件或目录
查看>>
php ffmpeg 推流库 --ffmpeg-push
查看>>
java 虚拟机垃圾回收机制相关解析
查看>>
iOS 富文本初探
查看>>
在Mac OS X多开某个应用程序窗口
查看>>