codeforces-148D Bag of mice【概率dp】
2016-05-22 15:32
323 查看
题意:
原来袋子里有w只白鼠和b只黑鼠
龙和王妃轮流从袋子里抓老鼠。谁先抓到白色老鼠谁就赢。
王妃每次抓一只老鼠,龙每次抓完一只老鼠之后袋里会有一只老鼠跑出来。
每次抓老鼠和跑出来的老鼠都是随机的。
如果两个人都没有抓到白色老鼠则龙赢。王妃先抓。
问王妃赢的概率。
dp(x,y,wch) 表示还有x只黑鼠,y只白鼠,到wch==0?王妃:龙 抓,王妃赢的概率
轮到王妃抓dp(x,y,0)的转移:
(1)抓只白的 dp(x,y,0)+=dp(x,y-1,1); 这时dp(x,y-1,1)== 有x只黑鼠y只白鼠,抓黑鼠的概率:y/(x+y);
(2)抓只黑的 dp(x,y,0)+=dp(x-1,y,1)*x/(x+y);
轮到龙抓dp(x,y,1)的转移,因为考虑的是王妃的胜率,所以龙抓白鼠的情况忽略:
(1)抓只黑的跑了黑的 dp(x,y,1)+=dp(x-2,y,0)*(x/(x+y))*((x-1)/(x+y-1));
(2)抓只黑的跑了白的 dp(x,y,1)+=dp(x-1,y-1,0)*(x/(x+y))*(y/(x+y-1));
特别的dp(x,0,0),dp(x,0,1) 王妃都必败 dp(0,y,0)王妃必胜,dp(0,y,1)王妃必败 。还有些边界问题的细节需要注意下。
我用的是记忆化搜索解决
原来袋子里有w只白鼠和b只黑鼠
龙和王妃轮流从袋子里抓老鼠。谁先抓到白色老鼠谁就赢。
王妃每次抓一只老鼠,龙每次抓完一只老鼠之后袋里会有一只老鼠跑出来。
每次抓老鼠和跑出来的老鼠都是随机的。
如果两个人都没有抓到白色老鼠则龙赢。王妃先抓。
问王妃赢的概率。
dp(x,y,wch) 表示还有x只黑鼠,y只白鼠,到wch==0?王妃:龙 抓,王妃赢的概率
轮到王妃抓dp(x,y,0)的转移:
(1)抓只白的 dp(x,y,0)+=dp(x,y-1,1); 这时dp(x,y-1,1)== 有x只黑鼠y只白鼠,抓黑鼠的概率:y/(x+y);
(2)抓只黑的 dp(x,y,0)+=dp(x-1,y,1)*x/(x+y);
轮到龙抓dp(x,y,1)的转移,因为考虑的是王妃的胜率,所以龙抓白鼠的情况忽略:
(1)抓只黑的跑了黑的 dp(x,y,1)+=dp(x-2,y,0)*(x/(x+y))*((x-1)/(x+y-1));
(2)抓只黑的跑了白的 dp(x,y,1)+=dp(x-1,y-1,0)*(x/(x+y))*(y/(x+y-1));
特别的dp(x,0,0),dp(x,0,1) 王妃都必败 dp(0,y,0)王妃必胜,dp(0,y,1)王妃必败 。还有些边界问题的细节需要注意下。
我用的是记忆化搜索解决
#include <stdio.h> #include <string.h> using namespace std; const int maxn=1008; const double eps=1E-8; double dp[maxn][maxn][2]; //还有x只黑鼠,y只白鼠,到wch==0?王妃:龙 抓,王妃赢的概率 int w,b; double DP(int x,int y,int wch) { // printf("%d %d %d\n",x,y,wch); if(!y) return 0;//没有白色王妃输 if(!x) {//没有黑色 if(!wch) return 1;//王妃抓白 else return 0; } double &res=dp[x][y][wch]; if(res>-0.5) return res;//已搜索过 res=0; double bk=(double)x,wt=(double)y; if(!wch) {//王妃抓 if(y>0) res=wt/(wt+bk);//抓白 if(x>0) res+=DP(x-1,y,1)*(bk/(wt+bk));//抓黑 } else {//让龙抓 //抓黑跑黑 if(x>1) res+=DP(x-2,y,0)*(bk*(bk-1)/((wt+bk)*(wt+bk-1))); //抓黑跑白 if(x>0&&y>0)res+=DP(x-1,y-1,0)*(bk*wt/((wt+bk)*(wt+bk-1))); } return res; } int main() { while(~scanf("%d%d",&w,&b)) { memset(dp,-1,sizeof(dp)); printf("%.10lf\n",DP(b,w,0)); } return 0; }
相关文章推荐
- xxx.java: Recompile with -Xlint:unchecked for details.
- 我的第一个博客测试
- 排列组合n选m C++实现
- Unix网络编程 5、6章笔记
- 回调函数思想
- Dialog中添加textview并修改文本内容
- bzoj 1006: [HNOI2008]神奇的国度(弦图 MCS算法)
- MyBatis Review——输入输出映射
- 线段树练习_codevs1080_树状数组
- Servlet的执行过程
- javascript实现标签切换代码示例
- find指令下的ctime、mtime和atime的区别
- 练习打字第十三天!
- 在linux下使用curl访问 多参数url GET参数问题
- struct和class的区别
- Maven 项目内置TOMCAT插件
- java封装通解
- intellij idea2016的web项目创建
- 开胃小菜—面向对象基础
- 3716: [PA2014]Muzeum 计算几何+贪心+set