题目链接: 剑指offer
题目描述: 把n个骰子仍在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
解题思路: 动态规划, dp(n, s) 表示扔第n个骰子, 和为s点数出现的次数。 dp(n, s) = dp(n-1, s-1) + dp(n-1, s-2) + ...... dp(n-1, s-6), 由于之和上一次有关, 所以我们只记录上一次的就值就可以了, 第一维大小就是2
代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <math.h> using namespace std; int g_maxValue=6; void PrintProbability(int n){ if(n<1) return; int* pProbability[2]; pProbability[0]=new int[g_maxValue*n+1]; pProbability[1]=new int[g_maxValue*n+1]; for(int i=0;i<=g_maxValue*n;i++){ pProbability[0][i]=0; pProbability[1][i]=0; } int flag=0; for(int i=1;i<=g_maxValue;i++) pProbability[flag][i]=1; for(int k=2;k<=n;k++){ for(int i=0;i<k;i++) pProbability[1-flag][i]=0; for(int i=k;i<=g_maxValue*k;i++){ pProbability[1-flag][i]=0; for(int j=1;j<=i && j<=g_maxValue;j++) pProbability[1-flag][i]+=pProbability[flag][i-j]; } flag=1-flag; } int total=pow((double)g_maxValue,n); double prob=0; for(int i=0;i<=g_maxValue*n;i++){ //cout<<pProbability[flag][i]<<endl; double ratio=(double)pProbability[flag][i]/total; prob+=ratio; cout<<i<<" "<<ratio<<" "<<endl; } cout<<prob<<endl; cout<<endl; delete[] pProbability[0]; delete[] pProbability[1]; } int main() { int n=5; PrintProbability(n); return 0; }
思考: 剑指offer上的代码啊......真的是好漂亮......多学着点