题意:有61个编号从0到60的站点,其中有几个里面有宝藏,通过掷筛子的方式决定每次前进几步,只能掷10次筛子,求能走到各个有宝藏的站点的概率
分析:
刚开始又习惯性的想着以每个站点为状态,写了代码出来样例错了,后来想到代码里没有管筛子只能用10次的事情。画出样例的计算过程图,发现用站点作为状态不行,因为在不同的步骤里站点会有不同的概率,不能用前面的站点的总概率来求后面站点的概率,想明白后:用两维,第一维表示所有站点,第二维表示掷筛子10次,这样就能表示所有的状态,而且符合计算过程了。
dp[i][j]:第j次掷筛子刚好走到第i个站点的概率,dp[i][j]+=dp[i-k][j-1]*p[k] 1<=k<=6
代码:
#include<iostream> #include<cstdio> #include<cstring> #define INF 100000000007 using namespace std; int t; double p[10],dp[100][20],a[20]; int main() { cin>>t; while(t--){ for(int i=1;i<=6;i++) cin>>p[i]; memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); for(int i=1;i<=6;i++) dp[i][1]=p[i]; for(int i=2;i<=10;i++){ for(int j=0;j<61;j++){ for(int k=1;k<=6;k++) if(j-k>=0) dp[j][i]+=dp[j-k][i-1]*p[k]; } } for(int i=10;i>0;i--) a[0]+=dp[5][i]; printf("5: %.1lf%%\n",a[0]*100); for(int i=10;i>0;i--) a[1]+=dp[12][i]; printf("12: %.1lf%%\n",a[1]*100); for(int i=10;i>0;i--) a[2]+=dp[22][i]; printf("22: %.1lf%%\n",a[2]*100); for(int i=10;i>0;i--) a[3]+=dp[29][i]; printf("29: %.1lf%%\n",a[3]*100); for(int i=10;i>0;i--) a[4]+=dp[33][i]; printf("33: %.1lf%%\n",a[4]*100); for(int i=10;i>0;i--) a[5]+=dp[38][i]; printf("38: %.1lf%%\n",a[5]*100); for(int i=10;i>0;i--) a[6]+=dp[42][i]; printf("42: %.1lf%%\n",a[6]*100); for(int i=10;i>0;i--) a[7]+=dp[46][i]; printf("46: %.1lf%%\n",a[7]*100); for(int i=10;i>0;i--) a[8]+=dp[50][i]; printf("50: %.1lf%%\n",a[8]*100); for(int i=10;i>0;i--) a[9]+=dp[55][i]; printf("55: %.1lf%%\n",a[9]*100); if(t) cout<<endl; } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
!HDU 1493 QQpet exploratory park-dp
原文地址:http://blog.csdn.net/ac_0_summer/article/details/46850059