题意:有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