http://community.topcoder.com/stat?c=problem_statement&pm=12498&rd=15495
ある位置が部分列に選ばれる確率を計算する。
ある位置の数字が"最終的に"その場所にある確率を計算する。
こういう列の要素のスワップの問題って、"その位置"と"他の位置"に分けて考えるのが定番なの?
class TheSwapsDivOne { public: double find(vector <string> v, int k) { string seq = accumulate(v.begin(), v.end(), string("")); const int N = seq.size(); double w[N]; fill(w, w + N, 0); double cnt[N]; fill(cnt, cnt + N, 0); double patt = 0; for (int i = 0; i < N; ++i) { for (int j = i + 1; j <= N; ++j) { for (int k = i; k < j; ++k) { ++cnt[k]; } ++patt; } } for (int i = 0; i < N; ++i) { w[i] = cnt[i] / patt; } const int K = 1000000 + 2; static double dp[K][2]; const int SAME = 0; const int OTHER = 1; fill(&dp[0][0], &dp[2 - 1][K - 1] + 1, 0); dp[0][SAME] = 1; for (int i = 0; i < k; ++i) { double whole = N * (N - 1); double a = ((N - 1) * (N - 2)) / whole; dp[i + 1][SAME] += dp[i][SAME] * a; double b = 2.0 / whole; dp[i + 1][SAME] += dp[i][OTHER] * b; double c = (2.0 * (N - 1)) / whole; dp[i + 1][OTHER] += dp[i][SAME] * c; double d = 0; d += (N - 1.0) * (N - 2.0) / whole; d += (2.0 * (N - 2.0)) / whole; dp[i + 1][OTHER] += dp[i][OTHER] * d; } const double W = accumulate(w, w + N, 0.0); double exp = 0; for (int i = 0; i < N; ++i) { double p = seq[i] - '0'; exp += dp[k][SAME] * w[i] * p; exp += dp[k][OTHER] * (W - w[i]) / (N - 1.0) * p; } return exp; }
0 件のコメント :
コメントを投稿