654:点击打开链接
递推题,写出递推式:a[i][j] = (a[i][j] + a[i - 1][j - k])
其中a[i][j]表是i个骰子扔出j点的方法数。当前的一个骰子投掷的点数是k,那么方法数就是i - 1个骰子投掷出j - k点的方法数,感觉有一点像整数划分……
#include <stdio.h>
int a[110][1010];
int main (void)
{
int m, k, i, j, l;
for(i = 1; i < 7; i++)
{
a[1][i] = 1;
}
for(i = 1; i < 110; i++)
{//i个骰子
for(j = i; j < 1010; j++)
{//j点
for(l = 1; l <= 6; l++)
{//第i个骰子的点数
if(j >= l)
a[i][j] = (a[i][j] + a[i - 1][j - l]) % 100007;
}
}
}
while(scanf("%d %d", &m, &k) != EOF)
printf("%d\n", a[m][k]);
return 0;
}
632: 点击打开链接
题目要求求概率,就是把小明胜的组合数除以总的组合数.其实是上一题的进一步计算.
用上一题的方法已经计算出i个骰子扔出j点的方法数,之后将小明胜的方法数和总的方法数计算出来即解决问题.
#include <stdio.h>
#include <math.h>
int dp[11][70];//dp[i][j]i个骰子去到j点的方法数
double p[12][12];//p[i][j]小明有i个骰子小红有j个骰子时小明的胜率
int main (void)
{
int i, j, k, h;
for(i = 0; i < 7; i++)
dp[1][i] = 1;
for(i = 2; i < 11; i++)
{
for(j = 2; j < 67; j++)
{
for(k = 1; k < 7; k++)
if(k < j)
dp[i][j] += dp[i - 1][j - k];
}
}
double sum;
for(i = 1; i < 11; i++)
{//i表示小明有几个骰子
for(j = 1; j < 11; j++)
{//j是小红有几个骰子
sum = 0.0;//小明胜的方法数
for(k = 1; k < 70; k++)
{//k表示小明去到的点数
for(h = 1; h < k; h++)
{//h是小红取到的点数,因为计算的是小明胜的方法数,所以h要小于k
sum += (double)dp[i][k] * dp[j][h];//注意强制类型转化
}
}
double temp = (double)pow(6, i + j);//总的方法数
p[i][j] = sum / temp;
}
}
int t;
scanf("%d", &t);
while(t --)
{
int m, n;
scanf("%d %d", &m, &n);
printf("%lf\n", p[m][n]);
}
return 0;
}