Http://acm.hust.edu.cn: 8080/judge/contest/view. Action? Cid = 11975 # Problem/I
A probability question. Or recursive questions.
Use DP [pre] [I] [J] to indicate that I is correct and J is incorrect.
Use DP [now] [I] [J] to indicate that the next State has an I-correct question and J-incorrect question.
If you are a student W, he has two options.
Correct a question or make no changes.
If he makes a mistake, he can only select one from the right. If he does not move, he will select from the wrong question, and the wrong question cannot be changed. The status is as follows:
If (I> 0)
DP [now] [I-1] [J + 1] + = DP [pre] [I] [J] * I/(n-stepw );
DP [now] [I] [J] + = DP [pre] [I] [J] * (J-stepw)/(n-stepw );
}
Similarly, K's principle is the same.
If (j> 0)
DP [now] [I + 1] [J-1] + = DP [pre] [I] [J] * j/(n-stepk );
DP [now] [I] [J] + = DP [pre] [I] [J] * (I-stepk)/(n-stepk );
If K or W have successively changed n questions, they should jump out and have no questions for him to change. After jumping out, because the next status has not been calculated. At this time, there is no next status and the previous status has not changed, so copy directly
(Nima we write memcpy as memcmp, and the result of WA is dying ...)
Use a rolling array.
Pre and now are two pointers.
# Include <iostream> # include <stdio. h> # include <string. h ># include <string >#include <algorithm> using namespace STD; double DP [2] [20] [20]; int pre, now; int N; double solve () {// cout <"^" <Endl; Pre = 0; now = 1; // DP [pre] [N] [0] = 1; char who [20]; int stepw = 0; int stepk = 0; int I, j; memset (DP, 0, sizeof (DP )); DP [pre] [N] [0] = 1; while (CIN> who) {// cout <who <"@" <Endl; if (who [0] = 'E') break; else for (I = 0; I <= N; I ++ ){ J = n-I; If (who [0] = 'W') {If (stepw> = N) break; if (I> 0) DP [now] [I-1] [J + 1] + = DP [pre] [I] [J] * I/(n-stepw ); // you should have the correct questions, select DP [now] [I] [J] + = DP [pre] [I] [J] * (J-stepw)/(n-stepw) from the correct menu ); // do not change. select from the error. You cannot select the previous} else if (who [0] = 'k') {If (stepk> = N) break; If (j> 0) DP [now] [I + 1] [J-1] + = DP [pre] [I] [J] * j/(n-stepk ); // you should have the wrong question, select DP [now] [I] [J] + = DP [pre] [I] [J] * (I-stepk)/(n-stepk) from the correct menu ); // do not change. select from the correct one. You cannot select the previous}/* For (int l = 0; L <2; l ++) {for (int K = 0; k <= N; k ++) {for (int o = 0; O <= N; O ++) cout <DP [l] [k] [O] <""; cout <Endl ;}cout <Endl ;}*/} if (I! = N + 1) memcpy (DP [now], DP [pre], sizeof (DP [0]); // It's memcpy, not memcmp if (who [0] = 'W') stepw ++, stepk = 0; else if (who [0] = 'k ') stepk ++, stepw = 0; swap (PRE, now); // exchange pointer memset (DP [now], 0, sizeof (DP [now]);} return DP [pre] [N] [0];} int main () {While (CIN> N) {getchar (); printf ("%. 2lf \ n ", solve ();} return 0 ;}