标签:style blog http color os io ar for 2014
概率dp
假设关系;
递归;
倒着求
#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 ) ;
然后递归求解(最好不要递归容易爆栈)
#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;
由于此点一定不在路径上
所以随便赋值
#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 还有飞行线
和上题一样
#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
标签:style blog http color os io ar for 2014
原文地址:http://www.cnblogs.com/17--/p/3960200.html