题目链接:http://codeforces.com/problemset/problem/148/D

题意:

  一个袋子中有w只白老鼠,b只黑老鼠。

  公主和龙轮流从袋子里随机抓一只老鼠出来,不放回,公主先拿。

  公主每次抓一只出来。龙每次在抓一只出来之后,会随机有一只老鼠跳出来(被龙吓的了。。。)。

  先抓到白老鼠的人赢。若两人最后都没有抓到白老鼠,则龙赢。

  问你公主赢的概率。

题解:

  表示状态:

    dp[i][j] = probability to win(当前公主先手,公主赢的概率)

    i:剩i只白老鼠

    j:剩j只黑老鼠

  找出答案:

    ans = dp[w][b]

  边界条件:

    if i==0 dp[i][j] = 0 (没有白老鼠了,不可能赢)

    else if j==0 dp[i][j] = 1 (有且只有白老鼠,一定赢)

    else if j==1 dp[i][j] = i/(i+1) (如果公主拿了黑老鼠,那么龙一定会拿到白老鼠,公主输。所以公主一下就要拿到白老鼠)

  如何转移:

    对于dp[i][j],有两种赢的方法:

      (1)公主在这个回合一次就抓到了白老鼠。

      (2)公主和龙都各抓了一只黑老鼠,然后公主在下一个回合赢了。

    P(一次就抓到了白老鼠) = i/(i+j)

    P(进入下个回合,即两人都抓到黑老鼠) = P(公主抓到黑老鼠) * P(龙抓到黑老鼠) = j/(i+j) * (j-1)/(i+j-1)

    所以dp[i][j] = P(一次就抓到了白老鼠) + P(进入下个回合) * P(在下个回合赢)

    

    那么考虑下个回合可能的状态。

    因为公主和龙都已经抓走了两只黑老鼠,那么下个回合取决于跳出来的老鼠,有三种可能:

      (1)跳出来白老鼠

      (2)跳出来黑老鼠

      (3)老鼠已经抓完了,没有老鼠跳出来

    对于情况(3),原状态(i,j)只可能为:(1,1) , (0,2) , (2,0),均包含在边界条件中,所以不作考虑。

    剩下两种情况的可能性:

      (1)P(跳出来白老鼠) = i/(i+j-2) (i>=1 and j>=2)

      (2)P(跳出来黑老鼠) = (j-2)/(i+j-2) (j>=3)

    所以P(在下个回合赢) = P(跳出来白老鼠) * dp[i-1][j-2] + P(跳出来黑老鼠) * dp[i][j-3]

    总方程:

      nex = 0

      if i>=1 and j>=2 nex += i/(i+j-2)*dp[i-1][j-2]

      if j>=3 nex += (j-2)/(i+j-2)*dp[i][j-3]

      dp[i][j] = i/(i+j) + j/(i+j) * (j-1)/(i+j-1) * nex

  另外,这道题的题解有两个版本,一种记忆化搜索,一种for循环版,都差不多。

AC Code(记忆化搜索):

 // state expression:
// dp[i][j] = probability to win
// i: i white mice
// j: j black mice
//
// find the answer:
// ans = dp[w][b]
//
// transferring:
// if i>=1 and j>=2 nex += i/(i+j-2)*dp[i-1][j-2]
// if j>=3 nex += (j-2)/(i+j-2)*dp[i][j-3]
// dp[i][j] = i/(i+j) + j/(i+j) * (j-1)/(i+j-1) * nex
//
// boundary:
// if i==0 dp[i][j] = 0
// if j==0 dp[i][j] = 1
// if j==1 dp[i][j] = i/(i+1)
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 1005 using namespace std; int w,b;
bool vis[MAX_N][MAX_N];
double ans;
double dp[MAX_N][MAX_N]; double dfs(int i,int j)
{
if(vis[i][j]) return dp[i][j];
vis[i][j]=true;
if(i==) return dp[i][j]=;
if(j==) return dp[i][j]=;
if(j==) return dp[i][j]=(double)i/(i+);
double nex=;
nex+=(double)i/(i+j-)*dfs(i-,j-);
if(j>=) nex+=(double)(j-)/(i+j-)*dfs(i,j-);
return dp[i][j]=(double)i/(i+j)+(double)j/(i+j)*(j-)/(i+j-)*nex;
} void read()
{
cin>>w>>b;
} void solve()
{
memset(vis,false,sizeof(vis));
ans=dfs(w,b);
} void print()
{
printf("%.9f\n",ans);
} int main()
{
read();
solve();
print();
}

AC Code(for循环):

 #include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 1005 using namespace std; int w,b;
double ans;
double dp[MAX_N][MAX_N]; void read()
{
cin>>w>>b;
} void solve()
{
memset(dp,,sizeof(dp));
for(int i=;i<=w;i++)
{
for(int j=;j<=b;j++)
{
if(i==)
{
dp[i][j]=;
continue;
}
if(j==)
{
dp[i][j]=;
continue;
}
if(j==)
{
dp[i][j]=(double)i/(i+);
continue;
}
double nex=(double)i/(i+j-)*dp[i-][j-];
if(j>=) nex+=(double)(j-)/(i+j-)*dp[i][j-];
dp[i][j]=(double)i/(i+j)+(double)j/(i+j)*(j-)/(i+j-)*nex;
}
}
} void print()
{
printf("%.9f\n",dp[w][b]);
} int main()
{
read();
solve();
print();
}

Codeforces 148D Bag of mice:概率dp 记忆化搜索的更多相关文章

  1. codeforces 148D Bag of mice(概率dp)

    题意:给你w个白色小鼠和b个黑色小鼠,把他们放到袋子里,princess先取,dragon后取,princess取的时候从剩下的当当中任意取一个,dragon取得时候也是从剩下的时候任取一个,但是取完 ...

  2. Codeforces 148D Bag of mice 概率dp(水

    题目链接:http://codeforces.com/problemset/problem/148/D 题意: 原来袋子里有w仅仅白鼠和b仅仅黑鼠 龙和王妃轮流从袋子里抓老鼠. 谁先抓到白色老师谁就赢 ...

  3. CodeForces 398B 概率DP 记忆化搜索

    题目:http://codeforces.com/contest/398/problem/B 有点似曾相识的感觉,记忆中上次那个跟这个相似的 我是用了 暴力搜索过掉的,今天这个肯定不行了,dp方程想了 ...

  4. HDU 5001 概率DP || 记忆化搜索

    2014 ACM/ICPC Asia Regional Anshan Online 给N个点,M条边组成的图,每一步能够从一个点走到相邻任一点,概率同样,问D步后没走到过每一个点的概率 概率DP  測 ...

  5. HDU - 5001 Walk(概率dp+记忆化搜索)

    Walk I used to think I could be anything, but now I know that I couldn't do anything. So I started t ...

  6. CF 148D Bag of mice 概率dp 难度:0

    D. Bag of mice time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  7. codeforce 148D. Bag of mice[概率dp]

    D. Bag of mice time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  8. 抓老鼠 codeForce 148D - Bag of mice 概率DP

    设dp[i][j]为有白老鼠i只,黑老鼠j只时轮到公主取时,公主赢的概率. 那么当i = 0 时,为0 当j = 0时,为1 公主可直接取出白老鼠一只赢的概率为i/(i+j) 公主取出了黑老鼠,龙必然 ...

  9. hdu3559 Frost Chain (概率dp+记忆化搜索)

    Problem Description In the unimaginable popular DotA game, the hero Lich has a wonderful skill: Fros ...

随机推荐

  1. 怎么学习PS快?

      PS快速入门笔记 软件界面: 菜单栏, 工具箱 工具属性栏 悬浮面板 画布 ctrl + N 新建画布   如果需要出图:分辨率:300 颜色模式:CMYK 屏幕显示: 分辨率: 72 颜色模式: ...

  2. 从有序数组中查找某个值 low_bound

    二分搜索 题意: 给定长度为n的单调不下降数列a0, ...an-1和一个数k,求满足ai>=k条件的最小的i. 不存在的情况下输出n. 输入: 5        3 2 3 3 5 6 输出: ...

  3. 成都传智播客Java/PHP培训就业率高

    依据传智播客的数据统计,传智播客的学员有五分之中的一个的能在毕业前找到惬意的工作,一半的学员能在毕业后一个月之内找到惬意的工作,一般在毕业后两个月之内绝大多数同学都能找到惬意的工作.而且传智播客毕业学 ...

  4. fastJson 转换日期格式

    第一种方法: JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd"; String str = JSON.toJSONString(user,Seria ...

  5. Oracle在plsql中修改数据

    Oracle在plsql中想要修改数据,有两种方式: a.使用rowid+点击锁图标,语句为: select t.*,rowid from T_BIC_PLY_MAIN t;   b.使用for up ...

  6. Web安全系列(三):XSS 攻击进阶(挖掘漏洞)

    前言 在前些章节 (web安全系列(一):XSS 攻击基础及原理)以及(Web安全系列(二):XSS 攻击进阶(初探 XSS Payload))中,我详细介绍了 XSS 形成的原理以及 XSS 攻击的 ...

  7. 浅谈Generator和Promise原理及实现

    Generator 熟悉ES6语法的同学们肯定对Generator(生成器)函数不陌生,这是一个化异步为同步的利器. 栗子: function* abc() { let count = 0; whil ...

  8. 某个时间段关闭API

    def bet(): if 000000 < int(time.strftime("%H%M%S", time.localtime())) < 90000: print ...

  9. Linux进入单用户模式

    有时候配置linux的过程中,因为一些误操作导致系统初始化时堵塞或挂起而无法进入系统,原因往往是因为配置文件设置错误,部分文件被误删之类.遇到这种情况一般新手的做法就是重装(虚拟机不装白不装),但在实 ...

  10. Mongodb亿级数据量的性能测试

    进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目:   (所有插入都是单线程进行,所有读取都是多线程进行) 1) 普通插入性能 (插入的数据每条大约在1KB左右) 2) 批量插入性能 ...