[ACM] zoj 3329 one person game (Probabilistic DP with loops, clever conversion)

Source: Internet
Author: User

One person game Time Limit: 1 second memory limit: 32768 kb Special Judge

There is a very simple and interesting one-person game. You have 3 dice, namelyDie1,Die2AndDie3.Die1HasK1Faces.Die2HasK2Faces.Die3HasK3Faces. All the dice are fair dice, so the probability of rolling each value, 1K1,K2,K3Is exactly 1/K1, 1/K2And 1/K3. You have a counter, and the game is played as follow:

  1. Set the counter to 0 at first.
  2. Roll the 3 dice simultaneously. If the up-facing NumberDie1IsA, The up-facing NumberDie2IsBAnd the up-facing NumberDie3IsC, Set the counter to 0. Otherwise, add the counter by the total value of the 3 up-facing numbers.
  3. If the counter's number is still not greaterN, Go to step 2. Otherwise the game is ended.

Calculate the expectation of the number of times that you cast dice before the end of the game.

Input

There are multiple test cases. The first line of input is an integerT(0 <T<= 300) indicating the number of test cases. ThenTTest Cases Follow. Each test case is a line contains 7 non-negative integersN,K1,K2,K3,A,B,C(0 <=N<= 500, 1 <K1,K2,K3<= 6, 1 <=A<=K1, 1 <=B<=K2, 1 <=C<=K3).

Output

For each test case, output the answer in a single line. A relative error of 1e-8 will be accepted.

Sample Input

20 2 2 2 1 1 10 6 6 6 1 1 1

Sample output

1.1428571428571431.004651162790698
Author: Cao, Peng
Source: The 7th Zhejiang Provincial Collegiate Programming Contest


Solution:

There are three dice (which are represented by dice1, dice2, and dice3 below, which are too difficult to fight). Each dice has K1, K2, and K3 faces respectively, the numbers on each dice face are 1 to K1, 1 to K2, 1 to K3, and each DIC is even. Now, when you play a game, there is a splitter. The initial value is 0 and three dice are cast at the same time. If the number at the top of dice1 is a and the number at the top of dice2 is B, if the number displayed on the top of dice3 is C, the splitter clears 0. Otherwise, the splitter adds the sum of the Three dice numbers displayed on the top. When the score on the splitter is greater than N, the game ends, calculate the average number of dice times.

This question has a link and cannot be converted directly.

The following train of thought reprinted: http://blog.csdn.net/morgan_xww/article/details/6775853 idea too good! I added an explanation in the brackets.



Set E [I] to the expected number of times that the current score is I and the game is about to roll the dice.
Obviously E [> N] = 0; E [0] is the answer;
E [I] = Σ PK * E [I + k] + P0 * E [0] + 1;

PK indicates the probability that the number of points is K, P0 indicates the probability that the score is cleared.

(The current score is I. After throwing the dice, there are two situations. One is that K is the score obtained by the next round of rolling the dice, and it will not clear 0. K needs to be accumulated because there will be many kinds of scores, second, the next round of dice is just the case where it needs to be cleared)
It is found from the above that each e [I] contains e [0], while E [0] is what we require and is a fixed value.
Set E [I] = A [I] * E [0] + B [I];
Add it to the preceding formula:
E [I] = (Σ PK * A [I + k] + P0) * E [0] + Σ PK * B [I + k] + 1; (manually import it to see if you can obtain this formula)
Apparently,
A [I] = Σ PK * A [I + k] + P0;
B [I] = Σ PK * B [I + k] + 1;
When I> N:
E [I] = A [I] * E [0] + B [I] = 0;
Therefore, a [I> N] = B [I> N] = 0;
Calculate a [n], B [N], a [n-1], B [n-1]... A [0], B [0]; (the recursive relationship can be obtained, from the back to the front)
Then E [0] = B [0]/(1-A [0]); (Final answer)

Code:

# Include <iostream> # include <stdio. h> # include <iomanip> # include <string. h> using namespace STD; const int maxn = 520; Double A [maxn]; Double B [maxn]; Double P [maxn]; // P [I] stores the probability double P0 with a score of I; // The probability int N, K1, K2, K3, a, B, C; void getp () {for (INT I = 1; I <= k1; I ++) for (Int J = 1; j <= k2; j ++) for (int K = 1; k <= K3; k ++) {if (I! = A | j! = B | K! = C) P [I + J + k] + = P0; // The probability of I + J + k is P0, this score can appear multiple times} int main () {int t; CIN> T; while (t --) {CIN> N> k1> k2> K3> A> B> C; memset (p, 0, sizeof (p); memset (, 0, sizeof (a); memset (B, 0, sizeof (B); p0 = 1.0/(K1 * K2 * K3); getp (); for (INT I = N; I> = 0; I --) // Original Score {for (Int J = 3; j <= k1 + k2 + K3; j ++) // The scores of the Three dice {A [I] + = P [J] * A [I + J]; // recursive formula B [I] + = P [J] * B [I + J];} A [I] + = P0; B [I] + = 1 ;} cout <setiosflags (IOs: fixed) <setprecision (15) <B [0]/(1-A [0]) <Endl;} return 0 ;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.