zoukankan      html  css  js  c++  java
  • [WOJ3010] 骰子

    题目描述:##

    骰子是一个六面分别刻有一到六点的立方体,每次投掷骰子,理论上得到(1)(6)的概率都是(1/6)

    有骰子一颗,连续投掷(n)次,问点数总和大于等于(X)的概率是多少?

    题目分析:##

    概率(DP)入门,由于是第一次做这类题,记录一下。

    首先概率题的主要思路:
    (概率 = 合法方案数 / 总方案数)

    对于这道题,总方案数(total=6^n),所以重点在于怎么求合法方案数,即抛掷(n)次总和大于(X)的次数。
    考虑(dp),设(f[i][j])表示抽第(i)次总点数为(j)的方案数,容易得到状态转移方程(f[i][j]=sumlimits_{k=1}^6{f[i-1][j-k]})
    $ ans = frac{sumlimits_{i=x}^{6*n}{f[n][i]}}{total} $

    代码:##

    #include<bits/stdc++.h>
    #define N 30
    #define M 300
    using namespace std;
    int read() {
    	int cnt = 0; int f = 1;
    	char c;
    	c = getchar();
    	while (!isdigit(c)) {
    		if (c == '-') f = -1;
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		cnt = cnt * 10 + c - '0';
    		c = getchar();
    	}
    	return cnt * f;
    }
    long long gcd(long long x, long long y) {
    	if (x == 0) return y;
    	return gcd(y % x, x);
    }
    long long f[N][M], n, x, tot = 1, ans = 0;
    int main() {
    	n = read(); x = read();
    	for (register int i = 1; i <= n; i++) tot *= 6;
    
    	f[0][0] = 1;
    	
    	for (register int i = 1; i <= n; i++) 
    		for (register int j = 1; j <= i * 6; j++) 
    			for (register int k = 1; k <= 6; k++)
    				if(j - k >= 0) 
    					f[i][j] += f[i-1][j-k];
    					
    	for (register int i = x; i <= 6 * n; i++) 
    		ans += f[n][i];
    		
    	if (ans == 0) {
    		printf("0");
    		return 0;
    	}
    	
    	if (ans == tot) {
    		printf("1");
    		return 0;
    	}
    	
    	long long GCD = gcd(ans, tot);
    	ans /= GCD; tot /= GCD;
    	printf("%lld/%lld", ans, tot);
    	return 0;
    }
    
  • 相关阅读:
    OAuth 2.0之授权码模式
    Rest和Restful & http
    HTTP1.1协议中文版-RFC2616
    Linux中安装Python2.7
    CvMat、Mat、IplImage之间的转换详解及实例
    ROS Node/Topic/Message/Service的一些问题
    ROS的tf_tree相关
    机器人路径规划(包括行人检测及动态避障总结)(长期更新)
    相关博客链接(长期更新)
    关于视觉里程计以及VI融合的相关研究(长期更新)
  • 原文地址:https://www.cnblogs.com/kma093/p/10740022.html
Copyright © 2011-2022 走看看