面试训练 n个骰子的点数

来源:互联网 发布:中国象棋ai算法 html5 编辑:程序博客网 时间:2024/05/16 13:47

题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。


要用动态规划,思路还需考虑。。。。


这道题目有一个简单的方法,就是使用递归来解决。

思路 第一个骰子 1-6中的某一个,后面依次n-1个筛子。只要计算某个和就好了吧

#include "stdio.h"int gMax=6;void propCount(int origin,int number,int sum,int *prop){int i=1;if(number==1){prop[sum-origin]++;}else{for(i=1;i<=gMax;i++){propCount(origin,number-1,sum+i,prop);}}}void getProp(int num){int sum=0;int i=0;int *prop=(int *)malloc(sizeof(int)*(num*gMax-num+1));memset(prop,0,sizeof(int)*(num*gMax-num+1));if(num<=0)return;for(i=1;i<=gMax;i++)propCount(num,num,sum+i,prop);for(i=0;i<num*gMax-num+1;i++)printf("%d ",prop[i]);free(prop);}int main(){int num =3;getProp(num);return 0;}

通过看书发现,书上面的思路是通过骰子数目的递增来 建立关系。

需要设置两个数组

第一个数组  n表示 此时筛子和为n,的次数总和。

第二个数组 添加了一个筛子  n代表n-1,n-2,n-3,n-4,n-5,n-6个次数之和。

看书上的实现很有技巧,我还是花了一段时间 才大致看明白原理。

#include "stdio.h"int gMax=6;#define MAX 1024void getProp(int num){int prop[2][MAX];int i=0,j=0;int flag=0;int k;for(i=0;i<MAX;i++){prop[0][i] =0;prop[1][i] =0;}flag=0;/*当只有一个骰子时 显然1-6出现次数均为1*/for(i=1;i<=gMax;i++)prop[flag][i]=1;for(k=2;k<=num;k++){/*显然当筛子数目增加1的时候 小于k的都不存在了*/for(i=0;i<k;i++)prop[1-flag][i]=0;for(j=k;j<=gMax*k;j++){prop[1-flag][j]=0;/*f(n)=f(n-1)+f(n-2)+f(n-3)+...f(n-6)出现的次数*/for(i=1;i<=j&&i<=gMax;i++){prop[1-flag][j]+=prop[flag][j-i];}}flag =1-flag;/*此时flag为什么需要交叠出现呢*//* k=1 prop[0][1]=prop[0][2]=...prop=[6]=1*//*     此时1-flag=1 即prop[1][2]....存放prop[1][n]当然就为之前存放的prop[0][n-1]+prop[0][n-2]+....prop[0][n-6]次数之和咯*//*k=2时刚好交替循环了*/}for(i=num;i<=num*gMax;i++){printf("%d ",prop[flag][i]);}}int main(){int num=3;getProp(num);return 0;}