n个骰子的点数。把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。
思想:F(n,s) = F(n-1,s-6)+F(n-1,s-5)+F(n-1,s-4)+F(n-1,s-3)+F(n-1,s-2)+F(n-1,s-1);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int power(int base,unsigned int n)
{
if(n==0) return 1;
if(n==1) return base;
int half=power(base,n>>1);
return ((n & 1) == 1 ? base : 1) * half * half;
}
//递归
int F(int n, int s)
{
if(s<n || s>6*n) return 0;
if(n==1) return 1;
//if(s==n || s==6*n) return 1;
else
return F(n-1,s-6)+F(n-1,s-5)+F(n-1,s-4)+F(n-1,s-3)+F(n-1,s-2)+F(n-1,s-1);
}
void listDiceProbability(int n)
{
int i=0;
unsigned int nTotal=power(6,n);
for(i=n;i<=6*n;i++)
{
printf("P(s=%d) = %d/%d\n",i,F(n,i),nTotal);
}
}
//非递归
void pr_probabilityOfDices(unsigned int N)
{
const unsigned int MAX = 12;
int i=0,size=0,s,n;
if (N > MAX)
{
printf("too big!\n");
return;
}
// new array
int **f=malloc(sizeof(int *)*(N+1));
for(i=1;i<N+1;i++)
{
size=sizeof(int)*(6*i+1);
f[i]=(int *)malloc(size);
memset(f[i],0,size);
}
//init
for(i=1;i<=6;i++)
{
f[1][i]=1;
}
//update
for(n=2;n<N+1;n++)
{
for(s=n;s<=(n*6);s++)
{
f[n][s]=0;
for(i=1;i<=6;i++)
if(s-i>=n-1 && s-i <= 6*(n-1))
f[n][s]+=f[n-1][s-i];
}
}
unsigned int ntotal=power(6,N);
for(i=N;i<6*N+1;i++)
{
printf("p(s=%d) = %d/%d \n",i,f[N][i],ntotal);
}
//free array
for(i=1;i<N+1;i++)
free(f[i]);
free(f);
}
//同上
void PrintSumProbabilityOfDices(unsigned int N)
{
const unsigned int MAX=12; //max number of dices
if(N>MAX)
{
printf("Overflow!\n");
return;
};
unsigned int a[MAX+1][6*MAX+1];
unsigned int n,s,i;
memset(a,0,sizeof(a));
for(s=1;s<=6;s++)
a[1][s]=1;
for(n=2;n<=N;n++)
for(s=n;s<=6*n;s++)
{
a[n][s]=0;
for(i=1;i<=6 && i<s;i++)
a[n][s]+=a[n-1][s-i];
}
unsigned int nTotal=power(6,N);
for(i=N;i<=6*N;i++)
{
printf("P(s=%d) = %d/%d\n",i,a[N][i],nTotal);
}
}
int main(void)
{
puts("***********");
listDiceProbability(3);
puts("***********");
pr_probabilityOfDices(3);
return 0;
}