qa5752707 確率
こんなプログラムを書いてみました。
実行結果も示します。
(2)回目の試行後
(0)=847660528
(16)=124692750
(17)=244296000
(18)=263381625
(19)=143071500
(20)=30045015
(40)=42173638
確率(千分率):49
(3)回目の試行後
(0)=1076017653276847424
(22)=30545324589780000
(23)=82860786328320000
(24)=111864923974732500
(25)=85643950494960000
(26)=38287113096053250
(27)=10271284971948000
(28)=1688428190699250
(29)=151390821582000
(30)=5550996791340
(40)=714698899811981084
確率(千分率):664
package test;
import java.math.BigInteger;
public class QA5752707 {
/**
* @param args
*/
public static void main(String[] args) {
// 現在の状態
java.math.BigInteger[] mx = new java.math.BigInteger[42];
// 試行後の状態
java.math.BigInteger[] mnext = new java.math.BigInteger[42];
//まず初期化
for(int i=0;i<41;i++){
mnext[i] = BigInteger.ZERO;
}
mnext[10] = BigInteger.ONE;
mnext[0] = BigInteger.ONE;
//計算用ワーク
java.math.BigInteger ret;
int addidx;
//何回か繰り返す
for(int kaisu = 2;kaisu<5;kaisu++){
for(int i=0;i<41;i++){
mnext[i] = BigInteger.ZERO;
}
//現在の状態から、試行後の状態を計算
for(int i = 10; i < 41; i++){
if(mx[i] != BigInteger.ZERO){
//10枚中印の付いたカードが0枚~10枚
for(int xx = 0; xx <= 10; xx++){
//5枚以上印が付いていないなら
if(xx < 5 && i < 35){
//印の付いたカードが(10-x)枚増える
addidx = i + 10 - xx;
}else{
addidx = 40;
}
//遷移後の確率を計算
//整数演算するために、10C40倍する
if(i != 40){
ret = mx[i].multiply(ccom(i,xx));
ret = ret.multiply(ccom(40-i,10-xx));
}else{
ret = mx[i].multiply(ccom(40,10));
}
//ret = ret.divide(ccom(40,10));
//試行後の値を加算
mnext[addidx] = mnext[addidx].add(ret);
//合計を加算
mnext[0] = mnext[0].add(ret);
}
}
}
System.out.println("(" + kaisu + ")回目の試行後");
for(int i = 0; i < 41; i++){
if(mnext[i] != BigInteger.ZERO){
System.out.println("("+i+")="+mnext[i].toString());
}
}
ret = mnext[40].multiply(BigInteger.valueOf(1000)).divide(mnext[0]);
System.out.println("確率(千分率):" + ret.toString());
System.out.println("");
}
}
/**
* 組み合わせを計算する
* @param a
* @param m
* 異なる a 個のものから異なる m 個のものを選ぶ
* @return
* 組み合わせ数
*/
public static BigInteger ccom(long a,long m){
java.math.BigInteger ret = factorial2(BigInteger.valueOf(a)) ;
ret=ret.divide(factorial2(BigInteger.valueOf(m)));
ret=ret.divide(factorial2(BigInteger.valueOf(a-m)));
return ret;
}
/**
* 階乗を計算する。
* @param val 階乗を計算する値
* @return val!
*/
public static BigInteger factorial2(BigInteger val) {
if (val.compareTo(BigInteger.ONE) <= 0) {
// val が 1以下になったら再帰呼び出しを終了する。
return BigInteger.ONE;
} else {
// val * (val - 1)!
return val.multiply(factorial2(val.subtract(BigInteger.ONE)));
}
}
}
こんなプログラムを書いてみました。
実行結果も示します。
(2)回目の試行後
(0)=847660528
(16)=124692750
(17)=244296000
(18)=263381625
(19)=143071500
(20)=30045015
(40)=42173638
確率(千分率):49
(3)回目の試行後
(0)=1076017653276847424
(22)=30545324589780000
(23)=82860786328320000
(24)=111864923974732500
(25)=85643950494960000
(26)=38287113096053250
(27)=10271284971948000
(28)=1688428190699250
(29)=151390821582000
(30)=5550996791340
(40)=714698899811981084
確率(千分率):664
package test;
import java.math.BigInteger;
public class QA5752707 {
/**
* @param args
*/
public static void main(String[] args) {
// 現在の状態
java.math.BigInteger[] mx = new java.math.BigInteger[42];
// 試行後の状態
java.math.BigInteger[] mnext = new java.math.BigInteger[42];
//まず初期化
for(int i=0;i<41;i++){
mnext[i] = BigInteger.ZERO;
}
mnext[10] = BigInteger.ONE;
mnext[0] = BigInteger.ONE;
//計算用ワーク
java.math.BigInteger ret;
int addidx;
//何回か繰り返す
for(int kaisu = 2;kaisu<5;kaisu++){
for(int i=0;i<41;i++){
mnext[i] = BigInteger.ZERO;
}
//現在の状態から、試行後の状態を計算
for(int i = 10; i < 41; i++){
if(mx[i] != BigInteger.ZERO){
//10枚中印の付いたカードが0枚~10枚
for(int xx = 0; xx <= 10; xx++){
//5枚以上印が付いていないなら
if(xx < 5 && i < 35){
//印の付いたカードが(10-x)枚増える
addidx = i + 10 - xx;
}else{
addidx = 40;
}
//遷移後の確率を計算
//整数演算するために、10C40倍する
if(i != 40){
ret = mx[i].multiply(ccom(i,xx));
ret = ret.multiply(ccom(40-i,10-xx));
}else{
ret = mx[i].multiply(ccom(40,10));
}
//ret = ret.divide(ccom(40,10));
//試行後の値を加算
mnext[addidx] = mnext[addidx].add(ret);
//合計を加算
mnext[0] = mnext[0].add(ret);
}
}
}
System.out.println("(" + kaisu + ")回目の試行後");
for(int i = 0; i < 41; i++){
if(mnext[i] != BigInteger.ZERO){
System.out.println("("+i+")="+mnext[i].toString());
}
}
ret = mnext[40].multiply(BigInteger.valueOf(1000)).divide(mnext[0]);
System.out.println("確率(千分率):" + ret.toString());
System.out.println("");
}
}
/**
* 組み合わせを計算する
* @param a
* @param m
* 異なる a 個のものから異なる m 個のものを選ぶ
* @return
* 組み合わせ数
*/
public static BigInteger ccom(long a,long m){
java.math.BigInteger ret = factorial2(BigInteger.valueOf(a)) ;
ret=ret.divide(factorial2(BigInteger.valueOf(m)));
ret=ret.divide(factorial2(BigInteger.valueOf(a-m)));
return ret;
}
/**
* 階乗を計算する。
* @param val 階乗を計算する値
* @return val!
*/
public static BigInteger factorial2(BigInteger val) {
if (val.compareTo(BigInteger.ONE) <= 0) {
// val が 1以下になったら再帰呼び出しを終了する。
return BigInteger.ONE;
} else {
// val * (val - 1)!
return val.multiply(factorial2(val.subtract(BigInteger.ONE)));
}
}
}