剑指offer 面试题43 n个骰子的点数 DP

  题目链接: 剑指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

  代码: 

#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;
}
View Code

  思考: 剑指offer上的代码啊......真的是好漂亮......多学着点

posted on 2017-09-22 14:37  FriskyPuppy  阅读(242)  评论(0编辑  收藏  举报

导航