AOJ 1286: Expected Allowance 深さ優先探索で期待値を計算する
問題
Expected Allowance | Aizu Online Judge
サイコロの数n、サイコロ1つあたりの面の数m、削減量kが与えられる。サイコロを同時に振った時の合計値から削減量kを引いただけ金がもらえるが、その値が1未満の場合は1だけもらえる。この時の期待値を計算する。
解法
深さ優先探索でサイコロの目の合計値を出す。それぞれの合計値は同様に確からしいので、全て足してパターンの数mnで割ればそれが期待値になる。
コード
import java.io.IOException; import java.util.Scanner; public class Main { private static int diceNum; private static int sideNum; private static int cutback; public static void main(String[] args) throws IOException { Scanner scanner = new Scanner(System.in); while (true) { diceNum = scanner.nextInt();// サイコロの数 sideNum = scanner.nextInt();// サイコロの面の数 cutback = scanner.nextInt();// ピンハネ if (diceNum == 0) { scanner.close(); break; } int dfs = dfs(0, 0);// 深さ優先探索 double ans = dfs / Math.pow(sideNum, diceNum); System.out.println(ans); } } static int dfs(int sum, int depth) { if (depth < diceNum) { // 振ったサイコロの数がサイコロの数より少なかったら、もう一個振る int dfs = 0; for (int i = 1; i <= sideNum; i++) { dfs += dfs(sum + i, depth + 1); } /* * 返されてきた値を足していく。 それぞれの値は独立なので、全て足しあわせて順列の和で割れば期待値が出る。 */ return dfs; } else { // サイコロ全部振ったらその合計値を返す if (sum - cutback < 1) { return 1; } else { return sum - cutback; } } } }