题目大意:
就是现在公主和龙来玩一个游戏,从一个只有白老鼠和黑老鼠的袋子里拿老鼠出来,公主先手,公主每次从其中小心地拿出一只老鼠,每只老鼠都等可能的被拿出,如果公主拿出了白色的老鼠则公主赢,如果拿出黑色则由龙拿,龙等可能地从袋子中拿出一只老鼠,如果龙拿到白色的则赢,每次龙拿出老鼠后袋子中的老鼠陷入恐慌,会随机跑出一只老鼠,现在如果直到最后袋子里没有老鼠了都没有哪一方拿到白色的老鼠,则算龙赢,老鼠在离开袋子之后不会再次回到袋子里,求公主获胜的概率
大致思路:
就是一个普通的记忆化搜索,没什么好说的样子...具体细节见代码吧
代码如下:
Result : Accepted Memory : 15772 KB Time : 62 ms
/* * Author: Gatevin * Created Time: 2014/12/3 16:05:25 * File Name: Asuna.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; int a, c; double vis[1001][1001][2]; //当前有白老鼠w只, 黑色的b只, who代表当前谁先手的情况下, princess赢的概率, 记忆化搜索 double dfs(int w, int b, char who) { if(who == 'p')//princess先手 { if(w == 0) return 0;//没有白色的了,不可能赢 if(b == 0) return 1;//有白色且没有黑色一定赢 if(vis[w][b][0]) return vis[w][b][0]; return vis[w][b][0] = w*1.0/(w + b) + b*1.0/(w + b)*dfs(w, b - 1, 'd'); } else//dragon先手 { if(w == 0 || b == 0) return 0; if(vis[w][b][1]) return vis[w][b][1]; return vis[w][b][1] = b*1.0/(w + b)*( (b >= 2 ? (b*1.0 - 1)/(w + b - 1)*dfs(w, b - 2, 'p') : 0) + w*1.0/(w + b - 1)*dfs(w - 1, b - 1, 'p')); } } int main() { scanf("%d %d", &a, &c); memset(vis, 0, sizeof(vis)); double ans = dfs(a, c, 'p'); printf("%.9f\n", ans); return 0; }