码迷,mamicode.com
首页 > 其他好文 > 详细

20140907_概率dp

时间:2014-09-07 11:01:35      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   ar   for   2014   

概率dp

假设关系;

递归;

倒着求

POJ 2096

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
double p[1086][1086];
int x,y;
double dp(int i,int j)
{
    if(p[i][j]>=0)
        return p[i][j];
    if(i>x||j>y)
        return 0;
    if(i==x&&j==y)
        return 0;
    double xx=0.0;
    xx+=dp(i+1,j)*(x-i)*j/x/y;
    xx+=dp(i,j+1)*(y-j)*i/x/y;
    xx+=1.0;
    xx+=dp(i+1,j+1)*(y-j)*(x-i)/x/y;
    xx/=(1-(double)i*j/x/y);
    return p[i][j]=xx;

}
int main()
{
    while(scanf("%d%d",&x,&y)!=EOF)
    {
        for(int i=0;i<x+2;i++)
            for(int j=0;j<y+3;j++)
                p[i][j]=-1.0;
        p[x][y]=0;
        printf("%.9f\n",dp(0,0));
    }
    return 0;
}

有x种bug和y个系统

每次找到的bug有4种情况

1:属于已经找到的bug和系统中的

2:属于已找到的bug但是不属于系统中

3:不属于已找到的bug但是属于系统中的

4:不属于已找到的bug且不属于系统中的

dp[i,j] = p1*dp[i,j] + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] + 1; 

合并之后

dp[i,j] = ( 1 + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] )/( 1-p1 ) ;

然后递归求解(最好不要递归容易爆栈)

HDU 3853

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#define eps 1e-5
using namespace std;
double p[1086][1086];
int x,y;
double stay[1086][1086],xia[1086][1086],you[1085][1086];
bool vis[1086][1086];
double dp(int i,int j)
{
    if(i>=x||j>=y)
        return 0;
    if(vis[i][j])
        return p[i][j];
    vis[i][j]=true;
    p[i][j]=xia[i][j]*dp(i,j+1)+you[i][j]*dp(i+1,j)+2;
    if(fabs(1-stay[i][j])<eps)
        return p[i][j]=0;
    else
        return p[i][j]=(p[i][j]/(1-stay[i][j]));
}
int main()
{
    while(scanf("%d%d",&x,&y)!=EOF)
    {
        memset(vis,false,sizeof vis);
        memset(p,0,sizeof p);
        for(int i=0;i<x;i++)
        {
            for(int j=0;j<y;j++)
            {
                scanf("%lf%lf%lf",&stay[i][j],&xia[i][j],&you[i][j]);
            }
        }
        vis[x-1][y-1]=true;
        p[x-1][y-1]=0.0;
        printf("%.3lf\n",dp(0,0));
    }
    return 0;
}

一张地图 每次可以三种选择

1:下走

2:右走

3:不动

求到终点的期望

定义

dpij为ij到终点的期望

则dp[ij]=P1dp【ij】+p2dp【ij+1】+p3dp【i+1j】;

化简后转移就行

坑点

if(fabs(1-stay[i][j])<eps)
		return p[i][j]=0;
由于此点一定不在路径上
所以随便赋值

HDU 4405

#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#define eps 1e-5
using namespace std;
double p[100086];
bool vis[100086];
int next[100086],n,m;
double dp(int x)
{
    if(vis[x])
        return p[x];
    if(x>=n)
        return 0;
    double ret=0.0;
    for(int i=1;i<7;i++)
    {
        int y=x+i;
        while(next[y]!=-1)
            y=next[y];
        ret+=dp(y);
    }
    ret=ret/6+1;
    vis[x]=1;
    return p[x]=ret;

}
int main()
{
    while(scanf("%d%d",&n,&m),m+n)
    {
        memset(vis,false,sizeof vis);
        memset(next,-1,sizeof next);
        int a,b;
        for(int i=0;i<m;i++)
            scanf("%d%d",&a,&b),next[a]=b;
        printf("%.4f\n",dp(0));
    }
    return 0;
}

飞行棋

每次投点1-6 还有飞行线

和上题一样

ZOJ 3329

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#define eps 1e-5
using namespace std;
double ap[1086],bp[1086],p[186];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,k1,k2,k3,kkk,a,b,c;
        scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c);
        memset(p,0,sizeof p);
        kkk=k1+k2+k3;
        double pp;
        for(int i=1;i<=k1;i++)
        {
            for(int j=1;j<=k2;j++)
            {
                for(int k=1;k<=k3;k++)
                {
                    if(i==a&&j==b&&k==c)
                        pp=1.0/k1/k2/k3;
                    else
                        p[i+j+k]+=1.0/k1/k2/k3;
                }
            }
        }
        memset(ap,0,sizeof ap);
        memset(bp,0,sizeof bp);
        for(int i=n;i>=0;i--)
        {
            for(int j=1;j<=kkk;j++)
            {
                ap[i]+=ap[i+j]*p[j];
                bp[i]+=bp[i+j]*p[j];
            }
            ap[i]+=pp;
            bp[i]+=1;
        }
        printf("%.10f\n",bp[0]/(1.0-ap[0]));
    }
    return 0;
}

新类型 化等式求解

http://blog.csdn.net/morgan_xww/article/details/6774708

 

20140907_概率dp

标签:style   blog   http   color   os   io   ar   for   2014   

原文地址:http://www.cnblogs.com/17--/p/3960200.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!