题目链接: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. HDoj-1233-还是畅通project-prim算法

    还是畅通project Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  2. Java reference的种类及使用场景

    Java 中一共有 4 种类型的引用 : StrongReference. SoftReference. WeakReference 以及 PhantomReference (传说中的幽灵引用).这  ...

  3. ruby 作为嵌入脚本时使用的注意事项

    近期一直在採坑... 假设是作为嵌入式脚本使用ruby的话... 一定会遇到这2个问题... gem安装的,无法在嵌入时使用..为啥.? 由于你没require 'ruby gem' 出现 找不到 E ...

  4. [读书笔记] learn python the hard way书中 有关powershell 的一些小问题

    ex46中,创建自己的python,  当你激活环境时 .\.venvs\lpthw\ Scripts\activate 会报一个错误 此时需要以管理员身份运行PowerShell,(当前的PS不用关 ...

  5. 优志愿前端数据加密破解-python

    # coding=utf-8 import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "etiaky.sett ...

  6. jquery中的clone()方法

    jquery中不能直接把选择到的元素如$('div')添加到其他地方,而需要使用$('div')[0]等 clone()方法直接复制HTML代码,所以可以直接用来添加元素.

  7. 淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树

    OceanBase是阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务,支持数千亿条记录.数百TB数据上的SQL操作. 在阿里巴巴集团下,OceanBase数据库支持了多个重要业务的数据 ...

  8. 企业级API设计

    最近对service的API设计,在team内有些讨论,主要集中在API是足够抽象.通用好呢, 还是具体.易用好? 其实这个是要折衷的,通用的好处是以后更改API的可能性小,但坏处是想要通用,里面的字 ...

  9. java 匿名类和匿名方法

    package com.test; interface product{ int getPrice(); } public class News { /** * @param args */ publ ...

  10. ubuntu 安装时遇到 hash sum mismatch 处理方法

    ubuntu安装大软件时,下载经常容易出错,hash sum mismatch是其中一种,说到底还是网络不好,重试很多遍都是这个错误,最后的解决方案是把mismatch说的那个链接用firefox打开 ...