Codeforces Round #105 (Div. 2) D. Bag of mice 概率dp
题目链接:
http://codeforces.com/problemset/problem/148/D
D. Bag of mice
memory limit per test256 megabytes
输入
The only line of input data contains two integers w and b (0 ≤ w, b ≤ 1000).
输出
Output the probability of the princess winning. The answer is considered to be correct if its absolute or relative error does not exceed 10 - 9.
样例输入
1 3
样例输出
0.500000000
题意
公主和龙博弈,一个箱子里面有w只白色的老鼠,b只黑色的老鼠,每一轮可以向箱子里面随机抓一只老鼠,如果抓出来的是白鼠,则直接胜出,否则换人,龙抓的时候会同时下跑一只箱子里面的老鼠,这只老鼠也是随机的一只,公主比较温柔,不会下走额外的老鼠。公主先开始抓,问公主胜出的概率。
题解
dp[i][j][0]:表示现在是公主抓,并且箱子里面还剩i只白鼠、j只黑鼠的概率。
dp[i][j][1]:表示现在是龙抓,并且箱子里面还剩i只白鼠、j只黑鼠的概率。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef __int64 LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-9;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=1111;
int n;
int w,b;
double dp[maxn][maxn][2];
void init(){
clr(dp,0);
}
int main() {
init();
scf("%d%d",&w,&b);
dp[w][b][1]=0;
dp[w][b][0]=1;
double ans=0.0;
for(int i=w;i>=0;i--){
for(int j=b;j>=0;j--){
///必输
if(i==0){ continue; }
///这局分不出胜负
if(j-1>=0) dp[i][j-1][1]+=j*1.0/(i+j)*dp[i][j][0];
///这局就赢的概率
ans+=i*1.0/(i+j)*dp[i][j][0];
///抓到一只黑的,同时跑了一只黑的
if(j-2>=0) dp[i][j-2][0]+=1.0*j*(j-1)/((i+j)*(i+j-1))*dp[i][j][1];
///抓到一只黑的,同时跑了一只白的
if(j-1>=0) dp[i-1][j-1][0]+=1.0*i*j/((i+j)*(i+j-1))*dp[i][j][1];
}
}
prf("%.9lf\n",ans);
return 0;
}
//end-----------------------------------------------------------------------
记忆化搜索:
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef int LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=10000000000000000LL;
const double eps=1e-9;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=1111;
int w,b;
double dp[maxn][maxn][2];
double dfs(int x,int y,int z){
if(x<=0||y<0) return 0;
if(dp[x][y][z]>=eps) return dp[x][y][z];
double& res=dp[x][y][z]=0;
if(z==0){
res+=1.0*x/(x+y);
if(y>0) res+=1.0*y/(x+y)*dfs(x,y-1,z^1);
}else{
if(y>1) res+=1.0*y/(x+y)*(y-1)/(x+y-1)*dfs(x,y-2,z^1);
if(y>0) res+=1.0*y/(x+y)*x/(x+y-1)*dfs(x-1,y-1,z^1);
}
return res;
}
int main() {
clr(dp,-1);
scf("%d%d",&w,&b);
prf("%.9lf\n",dfs(w,b,0));
return 0;
}
//end-----------------------------------------------------------------------