CodeForces 148D Bag of mice [概率DP]

Description

The dragon and the princess are arguing about what to do on the New Year's Eve. The dragon suggests flying to the mountains to watch fairies dancing in the moonlight, while the princess thinks they should just go to bed early. They are desperate to come to an amicable agreement, so they decide to leave this up to chance.

They take turns drawing a mouse from a bag which initially contains w white and b black mice. The person who is the first to draw a white mouse wins. After each mouse drawn by the dragon the rest of mice in the bag panic, and one of them jumps out of the bag itself (the princess draws her mice carefully and doesn't scare other mice). Princess draws first. What is the probability of the princess winning?

If there are no more mice in the bag and nobody has drawn a white mouse, the dragon wins. Mice which jump out of the bag themselves are not considered to be drawn (do not define the winner). Once a mouse has left the bag, it never returns to it. Every mouse is drawn from the bag with the same probability as every other one, and every mouse jumps out of the bag with the same probability as every other one.

題意:

龍與女王因是否去看精靈跳舞產生了分歧,於是決定採取從袋子裏抓老鼠的方法來決定去不去看,袋子裏有w只白老鼠,b只黑老鼠,誰先抓到白老鼠誰贏,而龍在從袋子裏抓老鼠的時候會有一隻老鼠會跑掉,現在女王先抓,問最後女王贏的概率。(一開始題意讀不懂,後來才知道draw有抓的意思)

範圍:

w,b<=1000

解法:

知道了具體的題意就會發現這是一道很明顯的概率DP,DP[W][B]表示現在女王先手,且還有W只白老鼠,B只黑老鼠,此時女王贏的概率。

於是只需枚舉女王與龍抓到的老鼠顏色即可轉移,具體參考代碼,注意w與b可能在轉移時減爲負數,需要判掉。

代碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
    char c; int sgn; T bit=0.1;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
    ret*=sgn;
    return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

double dp[1111][1111];
bool vis[1111][1111];
int n,m;
double dfs(int i,int j){
    if(i==0)return 0.0;
    if(j==0)return 1.0;
    if(vis[i][j])return dp[i][j];
    
    vis[i][j]=1;
    dp[i][j]=double(i)/double(i+j);
    if(i>=1&&j>=2){
        dp[i][j]+=double(j)/double(i+j)*double(j-1)/double(i+j-1)*
                  double(i)/double(i+j-2)*dfs(i-1,j-2);
    }
    if(j>=3){
        dp[i][j]+=double(j)/double(i+j)*double(j-1)/double(i+j-1)*
                  double(j-2)/double(i+j-2)*dfs(i,j-3);
    }


    return dp[i][j];
}
int main(){
    scanff(n);
    scanff(m);
    double ans=0;

    printf("%.10f\n",dfs(n,m));

    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章