动态规划 概率 期望

poj 2096

详解见: http://blog.csdn.net/morgan_xww/article/details/6774708

View Code
#include<iostream>
using namespace std;
const int N = 2000;
double dp[N][N];
int n,s;
double dfs(int x,int y){
    if(x==n&&y==s) return 0;
    if(x>n||y>s) return 0;
    if(dp[x][y]!=0) return dp[x][y];
    dp[x+1][y]=dfs(x+1,y);
    dp[x][y+1]=dfs(x,y+1);
    dp[x+1][y+1]=dfs(x+1,y+1);
    return dp[x][y] = ( n*s + (n-x)*y*dp[x+1][y] + x*(s-y)*dp[x][y+1] + (n-x)*(s-y)*dp[x+1][y+1] )/( n*s - x*y );
}
int main(){
    while(cin>>n>>s){
        printf("%.4lf\n",dfs(0,0));
    }
}

hdu 3853

详解:http://blog.sina.com.cn/s/blog_51cea4040100tlg9.html

View Code
View Code 

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1100;
double dp[N][N],ar[N][N][5];
int n,m;
//dp[i][j]=-2 表示(i,j) 不能到达 (n,m) 点 ;
double dfs(int r,int c){
    if(dp[r][c]!=-1) return dp[r][c];

    dp[r+1][c]=dfs(r+1,c);
    dp[r][c+1]=dfs(r,c+1);
    dp[r][c]=0;
    if(r+1<=n&&dp[r+1][c]>=0) dp[r][c]+=(dp[r+1][c]+2)*ar[r][c][3];
    if(c+1<=m&&dp[r][c+1]>=0) dp[r][c]+=(dp[r][c+1]+2)*ar[r][c][2];
    if(!dp[r][c]) return dp[r][c]=-2;
    return dp[r][c]=( dp[r][c] + 2*ar[r][c][1] )/ (1-ar[r][c][1]);
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
            for(int k=1;k<=3;k++)
                scanf("%lf",&ar[i][j][k]);
            dp[i][j]=-1;
        }
        for(int i=1;i<=n+1;i++) dp[i][m+1]=-2;
        for(int i=1;i<=m+1;i++) dp[n+1][i]=-2;
        dp[n][m]=0;

        printf("%.3lf\n",dfs(1,1));    
    }
}

zoj 3582

 一个东东上下各有n个灯,灯有亮和暗两状态,起初都是暗的,每天每盏灯亮的概率是p,各个灯独立并且一个灯亮了就不会暗掉,问上下各至少有m盏灯亮的期望是多少天。

dp[i][j] 表示 上有i个灯亮,下有j个灯亮时的 期望 

View Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int N = 200;

int n,m;
double p,dp[N][N],c[N][N],p1[N],p2[N];
double dfs(int x,int y){
    if(dp[x][y]!=0) return dp[x][y];
    if(x>=m&&y>=m) return 0;
    for(int i=x;i<=n;i++){
        for(int j=y;j<=n;j++){
            if(i==x&&j==y) {
                dp[i][j]+=p2[2*n-x-y];
                continue;
            }
            dp[i][j]=dfs(i,j);
            dp[x][y]+=c[n-x][i-x]*p1[i-x]*p2[n-i]* 
                c[n-y][j-y]*p1[j-y]*p2[n-j]*
                (dp[i][j]+1);
        }
    }
    dp[x][y]=dp[x][y]/(1-p2[2*n-x-y]);
    return dp[x][y];
}
int main(){
    for(int i=0;i<N;i++)
        for(int j=0;j<N;j++) c[i][j]=1;
    for(int i=1;i<N;i++){
        for(int j=1;j<i;j++){
            c[i][j]=c[i-1][j]+c[i-1][j-1];
        }
    }
    //for(int i=0;i<=5;i++){
    //    for(int j=0;j<=i;j++)
    //        printf("%.0lf ",c[i][j]);
    //    printf("\n");
    //}
    
    while(scanf("%d%d%lf",&n,&m,&p)!=EOF){
        if(!n&&!m) return 0;
        p1[0]=1; for(int i=1;i<N;i++) p1[i]=p1[i-1]*p;
        p2[0]=1; for(int i=1;i<N;i++) p2[i]=p2[i-1]*(1-p);
        memset(dp,0,sizeof(dp));
        printf("%.6lf\n",dfs(0,0));

        //for(int i=0;i<=n;i++){
        //    for(int j=0;j<=n;j++)
        //        printf("%.6lf ",dp[i][j]);
        //    printf("\n");
        //}
    }
}

 

 

 

 

 

 

 

posted @ 2012-05-10 20:39  HaoHua_Lee  阅读(409)  评论(0编辑  收藏  举报