yukicoder No.75 回数の期待値の問題
問題
No.75 回数の期待値の問題 - yukicoder
1つのサイコロを繰り返し振り,出た目の合計をにする.
もしを上回ったら合計を0にリセットする.
サイコロの振る回数の期待値はいくらか.
解法1
絶対誤差か相対誤差がに収まればいいので
モンテカルロでも正解を出すことができる.
解法2
期待値DPと二分探索で解く.
期待値をと決めてしまえば,を超えた時は残り回でにできることになるので,DPをした時に無限ループせず期待値を求めることができる.
の時
の時
この結果が元の決めた期待値より大きいか小さいかで二部探索をすれば求める期待値に近づけることができる.
#include <iostream> #include <vector> #include <algorithm> #include <random> using namespace std; #define RREP(i,s,e) for (i = s; i >= e; i--) #define rrep(i,n) RREP(i,n-1,0) #define REP(i,s,e) for (i = s; i < e; i++) #define rep(i,n) REP(i,0,n) #define INF 100000000 typedef long long ll; int main() { int i, k; double ans = 0; default_random_engine e; uniform_int_distribution<int> u{1,6}; cin >> k; rep (i,500000) { int x = 0; int cnt = 0; while (x != k) { x += u(e); if (x > k) x = 0; cnt++; } ans += cnt; } cout << ans / 500000 << endl; return 0; }
#include <iostream> #include <vector> #include <algorithm> #include <random> using namespace std; #define RREP(i,s,e) for (i = s; i >= e; i--) #define rrep(i,n) RREP(i,n-1,0) #define REP(i,s,e) for (i = s; i <= e; i++) #define rep(i,n) REP(i,0,n-1) #define INF 100000000 typedef long long ll; int main() { int i, j, k; double dp[201]; double l, r; cin >> k; l = 0; r = 1200; while (l+0.01 < r && l*1.01 < r) { double m = (l+r) / 2; dp[0] = 0; REP (i,1,k) { dp[i] = 0; REP (j,1,6) { if (i-j < 0) dp[i] += m; else dp[i] += dp[i-j]; } dp[i] /= 6; dp[i]++; } if (dp[k] < m) r = m; else l = m; } cout << (r+l)/2 << endl; return 0; }