CF 148D

来源:互联网 发布:淘宝网ppt模板 编辑:程序博客网 时间:2024/05/17 04:28

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

————————————————————————————————————————

题目描述:有无聊的白富美和高帅富玩抓耗子,耗子有白色和黑色,两个人轮流,白富美先抓,高帅富后抓,高帅富比较凶猛,他抓完一次后,就会有一只小耗子从袋子里逃跑了。耗子被抓住和逃跑的概率是一样的。谁抓住白色耗子谁就赢了,如果最后没有白色耗子,也是白富美输。求白富美赢得概率。

————————————————————————————————————————

题目思路:

概率问题,用f[i][j]记录当总共有i个耗子,j个白耗子时白富美赢得概率。

注意初始化。

————————————————————————————————————————

源代码:

#include <iostream>#include<stdio.h>using namespace std;double f[2010][1010];int main(){    int w = 0,b = 0;    int i = 0,j = 0;    double temp = 0;    scanf("%d%d",&w,&b);    for(i = 1;i<=w+b;i++)      f[i][1] = 1/(double)i;    for(i = 1;i<=b;i++)      f[0][i] = 1;    for(i = 1;i<=w;i++)      f[i][i] = 1;    for(i = 3;i<=w+b;i++)    {        for(j = 1;j<=w && j<=i;j++)                         //这题这少加了个j<=i  , 比赛的时候没有ac,哎哎哎哎!!!伤心!!!       {           if(w>1)             temp = f[i-3][j-1]*j/(i-2)+f[i-3][j]*(i-2-j)/(i-2);           else             temp = f[i-3][j]*(i-2-j)/(i-2);           f[i][j] = (double)j/i+temp*(i-j)/i*(i-1-j)/(i-1);       }    }    printf("%.9lf",f[w+b][w]);    return 0;}
附上记忆化搜索两例:

一个用了两个函数交替模拟

另一个思路和我差不多,但用的记忆化搜索。

//by learn#include <iostream>#include <sstream>#include <vector>#include <algorithm>#include <cstdio>using namespace std;bool didf[1001][1001];bool didg[1001][1001];double _f[1001][1001];double _g[1001][1001];//f -- king//g -- pint b, w;double g(int b, int w);double f(int b, int w);double f(int b, int w){    if (!w)        return 1;    if (didf[b][w])        return _f[b][w];    didf[b][w] = true;    double &ret = _f[b][w];    ret = 1.0 * w / (b + w);    if (b)    {        if (b >= 2)            ret += (1 - g(b-2, w)) * b * 1.0 / (b + w) * (b - 1) * 1.0 / (b + w - 1);        if (w >= 1)            ret += (1 - g(b-1, w-1)) * b * 1.0 / (b + w) * w * 1.0 / (b + w - 1);    }    return ret;}double g(int b, int w){    if (!w)        return 0;    if (didg[b][w])        return _g[b][w];    didg[b][w] = true;    double &ret = _g[b][w];    ret = 1.0 * w / (b + w);    if (b)        ret += (1 - f(b-1, w)) * b * 1.0 / (b + w);    return ret;}int main(){    cin >> b >> w;    printf("%.10f\n", g(w, b));    return 0;}

//by HUST_LAZ#include <iostream>#include <cstring>#include <cstdio>#define maxn 1005using namespace std;int v[maxn][maxn];double f[maxn][maxn];double dp(int w,int b){    if (w<=0) return 0;    if (b<0) return 0;    if (v[w][b]) return f[w][b];    double ans;    double ans1=w*1.0/(w+b);    double ans2=0;    if (b>=2)    ans2=(b*1.0)/(w+b)*(b-1)/(w+b-1);    double ans3=0;    if (b>=2)    ans3=w*1.0/(w+b-2)*dp(w-1,b-2);    double ans4=0;    if (b>=3)    ans4=(b-2)*1.0/(w+b-2)*dp(w,b-3);    ans=ans1+ans2*(ans3+ans4);    f[w][b]=ans;    v[w][b]=1;    return ans;}int main(){    int w,b;    cin>>w>>b;    memset(v,0,sizeof(v));    printf("%.9lf\n",dp(w,b));    return 0;}


原创粉丝点击