求期望两种题型。
1.概率dp
2.高斯消元
这里有一篇很好的文章:http://kicd.blog.163.com/blog/static/126961911200910168335852/
还有kb大神的专题:http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html
然后是我AC的三道小题。全部是概率dp
poj-2096
dp[i][j]代表i,j到n,s的期望步数;
(i*(s-j)/(n*s))*dp[i][j+1]中,i/(n*s)代表在i中取一个的概率,(s-j)/(n*s)代表在s-j中取一个,放到j+1中的概率.dp[i][j+1]同时还代表取到i个n及j+1个s的状态。
'='代表dp[i][j]前一步的所有期望步数*概率的和+1步。
View Code
#include <iostream> #include <stdio.h> using namespace std; #define N 1005 #define S 1005 double dp[N][S]; int main() { int n,s; while(scanf("%d%d",&n,&s)!=EOF){ //for(int i=0;i<=n;i++) //for(int j=0;j<=s;j++) dp[n][s]=0; for(int i=n;i>=0;i--) for(int j=s;j>=0;j--) if(i==n && j==s) continue; else dp[i][j]=(i*(s-j)*dp[i][j+1]+(n-i)*j*dp[i+1][j]+(n-i)*(s-j)*dp[i+1][j+1]+n*s)/(n*s-i*j); printf("%.4f\n",dp[0][0]); } return 0; }
hdu-4405
View Code
#include <iostream> #include <string.h> #include <stdio.h> #define V 100005 #define E 1005 using namespace std; struct Edge{ int u,v,next; }edge[E]; int head[V],cnt; void init(){ cnt=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } int n,m,a,b; bool vis[V]; double dp[V]; int main() { while(scanf("%d%d",&n,&m)!=EOF){ if(n==0 && m==0) break; init(); memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); while(m--){ scanf("%d%d",&a,&b); addedge(b,a); } dp[n]=-1;//想走到自己,需要-1步 for(int i=n;i>=0;i--){ if(!vis[i]){ dp[i]+=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6.0+1.0; vis[i]=1; } for(int j=head[i];j!=-1;j=edge[j].next){ dp[edge[j].v]=dp[i]; vis[edge[j].v]=true; } } //for(int i=0;i<=n;i++) cout << dp[i] <<endl; printf("%.4lf\n",dp[0]); } return 0; }
hdu-3853
View Code
#include <math.h> #include <stdlib.h> #include <iostream> #include <stdio.h> #include <string.h> #define R 1005 #define C 1005 const double eps=1e-5; using namespace std; double dp[R][C]; int r,c; struct P{ double x,y,z; }p[R][C]; int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&r,&c)!=EOF){ for(int i=1;i<=r;i++){ for(int j=1;j<=c;j++){ scanf("%lf%lf%lf",&p[i][j].x,&p[i][j].y,&p[i][j].z); } } memset(dp,0,sizeof(dp)); dp[r][c]=0; for(int i=r;i>=1;i--){ for(int j=c;j>=1;j--){ if(i==r && j==c) continue; if(fabs(1-p[i][j].x)<eps) continue; dp[i][j]=(p[i][j].y*dp[i][j+1]+p[i][j].z*dp[i+1][j]+2.0)/(1.0-p[i][j].x); } } /*for(int i=1;i<=r;i++){ for(int j=1;j<=c;j++){ printf("%.3lf ",dp[i][j]); } printf("\n"); }*/ printf("%.3lf\n",dp[1][1]); } return 0; }
剑指杭州。