首页 > 代码库 > poj-2096-Collecting Bugs-概率DP
poj-2096-Collecting Bugs-概率DP
期望dp。
dp[x][y]:已经遇到x个bug,y个sub,还需要的期望步数。则:
设:p1=x/n;p2=(n-x)/n;p3=y/s;p4=(s-y)/s;
dp[x][y]=p1*p3*(dp[x][y]+1)
+p2*p4*(dp[x+1][y+1]+1)
+p2*p3*(dp[x+1][y]+1)
+p1*p4*(dp[x][y+1]+1).
把公式右边的dp[x][y]移到左边,然后两边同时除以1-p1*p3得:
dp[x][y]=(
p2*p4*(dp[x+1][y+1]+1)
+p2*p3*(dp[x+1][y]+1)
+p1*p4*(dp[x][y+1]+1)
)/(1-p1*p3);
这样,就可以用记忆化或者递推的方式求出dp[x][y]了。
#include <iostream> #include<stdio.h> #include<string.h> using namespace std; #define maxn 1100 double dp[maxn][maxn]; int n,s; double dos(int x,int y) { if(x>n||y>s)return -1; if(dp[x][y]>-0.5)return dp[x][y]; double p1,p2; double p3,p4; p1=1.0*x/n;p2=1.0*(n-x)/n; p3=(1.0*y)/s;p4=1.0*(s-y)/s; dp[x][y]=p1*p3; dp[x][y]+=p2*p4*(dos(x+1,y+1)+1); dp[x][y]+=p2*p3*(dos(x+1,y)+1); dp[x][y]+=p1*p4*(dos(x,y+1)+1); dp[x][y]=dp[x][y]/(1-p1*p3); return dp[x][y]; } int main() { while(~scanf("%d%d",&n,&s)) { memset(dp,-1,sizeof(dp)); dp[n][s]=0; printf("%.4f\n",dos(0,0)); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。