Question:
There are N dice, and each dice has K faces, respectively marked 1 ~ K. Set the value of each dice to fi. If sum (fi) is equal to S, get a score sco = mult (fi ).
Sum (fi) = f1 + f2 +... + fn
Mul (fi) = f1 * f2 *... * fn
Calculate the sum of all mul (fi.
The time limit is 2 s.
N (1 ≤ N ≤ 1000) K (1 ≤ K ≤ 1000) S (0 ≤ S ≤ 15000 ).
Question:
The sum (fi) of all N dice is the sum of all mul (fi) of S, and is set to ans [n] [s].
Obviously there are ans [n] [s] = ans [n-1] [s-1] + 2 * ans [n-1] [S-2] +... + k * ans [n-1] [s-k]
The above formula can be used as the state transition equation:
Dp [I] [j] = dp [I-1] [J-1] + 2 * dp [I-1] [J-2] +... + k * dp [I-1] [j-k]
If we use this transfer equation, it is not difficult to judge that the complexity is O (n * k * s), and it is definitely time-out.
In fact, we can look at the right side of the transfer equation as follows:
= Dp [I-1] [J-1] + dp [I-1] [J-2] +... + dp [I-1] [j-k]
+ Dp [I-1] [J-2] + dp [I-1] [J-3] +... + dp [I-1] [j-k]
.
.
.
+ Dp [I-1] [j-k]
We set sum [I] [j] = dp [I] [J-1] + dp [I] [J-2] +... + dp [I] [1]
The right side of the transfer equation can be viewed as follows:
= Sum [I-1] [J-1]-sum [I-1] [j-k-1]
+ Sum [I-1] [J-2]-sum [I-1] [j-k-1]
.
.
.
+ Sum [I-1] [j-k]-sum [I-1] [j-k-1]
Let's set ssum [I] [j] = sum [I] [j] + sum [I] [J-1] +... + sum [I] [1]
In this way, the right side of the transfer equation can be viewed
= Ssum [I] [J-1]-ssum [I] [j-k-1]-k * sum [I] [j-k-1]
In this way, we calculate O (k) For dp [I] [j] and convert it to O (1), and the overall complexity of the algorithm is reduced to O (n * s ), in this way, no timeout occurs.
But the space complexity is O (n * s), but we found that I only need to know the I-1, so we can use the rolling array to process, in this way, the space complexity is reduced to O (2 * s ).
It should be noted that when the j-k-1 <1, the transfer equation is slightly different, but it is only a small detail of the problem, it is easy to deal.
Code:
[Cpp]
# Pragma comment (linker, "/STACK: 102400000,102400000 ")
# Include <stdio. h>
# Include <string. h>
# Include <math. h>
# Include <stdlib. h>
# Include <ctype. h>
# Include <iostream>
# Include <algorithm>
# Include <stack>
# Include <queue>
# Include <map>
# Include <set>
# Include <vector>
# Include <string>
Using namespace std;
# Define ll _ int64
# Define clr (x, c, n) memset (x, c, sizeof (x [0]) * (n ))
# Define clr_all (x, c) memset (x, c, sizeof (x ))
# Define IT iterator
# Define ls rt <1
# Define rs ls | 1
# Define lson l, mid, ls
# Define rson mid + 1, r, rs
# Define middle l + r> 1
# Define MOD 100000007.
# Define inf 0x3f3f3f
# Define eps (1e-8)
# Define PI 3.1415926535897932384626433832795
# Define E 2.7182818284590452353602874713527
Template <class T> T _ min (T a, T B) {return a <B? A: B ;}
Template <class T> T _ max (T a, T B) {return a> B? A: B ;}
Template <class T> T _ abs (T a) {return a> 0? A:-;}
Template <class T> T _ mod (T a, T m) {return a <m? (A <0? (A % m + m) % m: a): a % m ;}
Template <class T> T _ gcd (T a, T B) {while (B) {T t = B; B = a % B; a = t ;} return ;}
Template <class T> void _ swap (T & a, T & B) {T t = B; B = a; a = t ;}
Template <class T> void getmax (T & a, T B) {a = a> B? A: B ;}
Template <class T> void getmin (T & a, T B) {a = (! =-1 & a <B )? A: B ;}
Int TS, cas = 1;
Const int M = 15000 + 5;
Ll n, k, s, m;
Ll dp [2] [2] [M], now, pre, tmp;
Void run (){
Ll I, j;
Scanf ("% lld", & n, & k, & s );
Now = 0;
Dp [now] [0] [0] = dp [now] [1] [0] = 0;
For (I = 1; I <= s; I ++ ){
Dp [now] [0] [I] = dp [now] [0] [I-1] + (I <= k? I: 0 );
Dp [now] [1] [I] = (dp [now] [1] [I-1] + dp [now] [0] [I]) % MOD;
}
For (I = 2; I <= n; I ++ ){
Pre = now;
Now ^ = 1;
Dp [now] [0] [I-1] = dp [now] [1] [I-1] = 0;
For (j = I; j <= s; j ++ ){
If (j <I + k) tmp = dp [pre] [1] [J-1];
Else tmp = (dp [pre] [1] [J-1]-dp [pre] [1] [j-k-1]-dp [pre] [0] [j-k-1] * k) % MOD + MOD) % MOD;
Dp [now] [0] [j] = (dp [now] [0] [J-1] + tmp) % MOD;
Dp [now] [1] [j] = (dp [now] [1] [J-1] + dp [now] [0] [j]) % MOD;
}
}
Printf ("Case % d: % lld \ n", cas, (dp [now] [0] [s]-dp [now] [0] [s-1]) % MOD + MOD) % MOD );
}
Void presof (){
}
Int main (){
// Freopen ("input.txt", "r", stdin );
// Freopen ("output.txt", "w", stdout );
Presof ();
// Run ();
// While (~ Scanf ("% d", & n) run ();
For (scanf ("% d", & TS), cas = 1; cas <= TS; cas ++) run ();
Return 0;
}