Title Link: HDOJ-5159
There are too many ways to do this problem. BC's second question can also be very water.
Algorithm One
The algorithm I wrote at the time of the game was this:
Preprocess out all the answers, and then output for each query directly.
Enquiries (A, b) are recorded as (A, b).
The answer to (a, b) is from the answer (A, b-1).
The answer to (a, 1) is the average of 1 to a, which is quite obvious.
If B > 1, then we consider in the first B, we draw each kind of card probability is 1/a, and then this card before b-1 the probability of not being drawn to ((A-1)/a) ^ (b-1), then the first B times the new expected score is
Sum (1~a) * ((A-1)/a) ^ (b-1) * (1/a). Then the answer to this value plus (A, b-1) is the answer to (a, b).
Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath > #include <algorithm>using namespace std;typedef double db;const int maxn = 100000 + 5, MAXM = 5 + 2;db ANS[MAXN] [Maxm];int Main () {int T, A, b;scanf ("%d", &t);D b t;for (int i = 1; I <= 100000; ++i) {for (int j = 1; J <= 5; + +J) {if (j = = 1) {Ans[i][j] = (db) (1 + i)/2.0;t = (db) (I-1)/(db) i;continue;} ANS[I][J] = Ans[i][j-1] + (db) (1 + i)/2.0 * T;IF (j = = 5) continue;t *= (db) (I-1)/(db) I;}} for (int case = 1; Case <= T; ++case) {scanf ("%d%d", &a, &b);p rintf ("Case #%d:%.3lf\n", case, Ans[a][b]);} return 0;}
Algorithm two
This algorithm is straightforward for (a, b), and it is much simpler to write.
We consider each card, if it is drawn in the B-time, the score will be added to its value, then it is in the B-time how much probability is pumped?
This is not a direct calculation, we consider that the B-time is not drawn to the probability of how much? This is obviously ((A-1)/a) ^ (b). So the probability of pumping it in B is 1-((A-1)/a) ^b, the probability of its value is the contribution of this card to the desired score.
So the answer is Sum (1~a) * (1-((A-1)/a) ^b).
Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath > #include <algorithm>using namespace std;typedef double db;const int maxn = 100000 + 5, MAXM = 5 + 2;db ANS[MAXN] [MAXM];D b Solve (int a, int b) {DB t = 1;for (int i = 1; I <= b; ++i) T *= (db) (a-1)/a;t = 1-t;return (db) (1 + a) * (DB) a/2.0 * t;} int main () {int T, A, b;scanf ("%d", &t); for (int case = 1; Case <= T; ++case) {scanf ("%d%d", &a, &b);p rintf ("Case #%d:%.3lf\n", Case, Solve (A, b));} return 0;}
[BC round#26] Card "All kinds of water"