九度 題目1255:骰子點數概率
阿新 • • 發佈:2019-01-31
- 題目描述:
-
把n個骰子扔在地上,所有骰子朝上一面的點數之和為S。輸入n,打印出S的所有可能的值出現的概率。
- 輸入:
-
輸入包括一個整數N(1<=N<=1000),代表有N個骰子。
- 輸出:
-
可能有多組測試資料,對於每組資料,
按照Sample Output的格式輸出每一個可能出現的和S的概率。
- 樣例輸入:
-
1 2
- 樣例輸出:
-
1: 0.167 2: 0.167 3: 0.167 4: 0.167 5: 0.167 6: 0.167 2: 0.028 3: 0.056 4: 0.083 5: 0.111 6: 0.139 7: 0.167 8: 0.139 9: 0.111 10: 0.083 11: 0.056
12: 0.028
-
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
一開始想到的是用概率公式去推。。。。。後來借鑑了大神們的做法,原來是用dp
-
因為如果現在是第K個骰子,當前結果n由第k-1個的結果n-1,n-2, n-3,n-4, n-5, n-6分別加1,2,3,4,5,6得出,事實上只需要保持二組資料:當前的結果和前一個骰子的結果。這裡用位與運算,用最後一位的奇偶性來區別。
-
#include<iostream> #include<string.h> #include<iomanip> #include<stdio.h> using namespace std; double ap[2][6003]; double a6[1003]; int main() { int i; a6[0]=1; for(i=1;i<1001;i++) a6[i]=6*a6[i-1]; int n; while(cin>>n) { memset(ap,0,sizeof(ap)); int j,k; ap[1][1]=1; ap[1][2]=1; ap[1][3]=1; ap[1][4]=1; ap[1][5]=1; ap[1][6]=1; for(j=2;j<=n;j++) { for(k=j;k<=6*j;k++) { ap[j&1][k]=0; for(i=1;k-i>0&&i<=6;i++) { ap[j&1][k]+=ap[(j+1)&1][k-i]; } } } for(i=n;i<=n*6;i++) printf("%d: %.3lf\n",i,ap[n&1][i]/a6[n]); printf("\n"); } } /************************************************************** Problem: 1255 User: 午夜小白龍 Language: C++ Result: Accepted Time:250 ms Memory:1620 kb ****************************************************************/