題意:有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;}}