动态规划 概率 期望
poj 2096
详解见: http://blog.csdn.net/morgan_xww/article/details/6774708
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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个灯亮时的 期望
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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"); //} } }