骰子(nyoj 654 && 632)

来源:互联网 发布:淘宝平邮无需物流 编辑:程序博客网 时间:2024/05/18 02:05

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;}

0 0
原创粉丝点击