ZOJ3662Math Magic (group backpack + full backpack), zoj3662mathmagic
I-Math MagicTime Limit:3000 MSMemory Limit:32768KB64bit IO Format:% Lld & % lluSubmit Status
Description
Yesterday, my teacher taught us about math: +,-, *,/, GCD, LCM... as you know, LCM (Least common multiple) of two positive numbers can be solved easily because of a * B = GCD (a, B) * LCM (a, B ).
In class, I raised a new idea: "how to calculate the LCM of K numbers ". it's also an easy problem indeed, which only cost me 1 minute to solve it. I raised my hand told teacher about my outstanding algorithm. teacher just smiled and smiled...
After class, my teacher gave me a new problem and he wanted me solve it in 1 minute, too. If we know three parameters N, M, K, and two equations:
1. SUM (A1, A2,..., Ai, Ai + 1,..., AK) = N
2. LCM (A1, A2,..., Ai, Ai + 1,..., AK) = M
Can you calculate how many kinds of solutions are there for Ai (Ai are all positive numbers). I began to roll cold sweat but teacher just smiled and smiled.
Can you solve this problem in 1 minute?
Input
There are multiple test cases.
Each test case contains three integers N, M, K. (1 ≤ N, M ≤ 1,000, 1 ≤ K ≤ 100)
Output
For each test case, output an integer indicating the number of solution modulo 1,000,000,007 (1e9 + 7 ).
You can get more details in the sample and hint below.
Sample Input
4 2 23 2 2
Sample Output
12
Hint
The first test case: the only solution is (2, 2 ).
The second test case: the solution are (1, 2) and (2, 1 ).
Q: K positive integers, N, and M are allowed.
Analysis: because the number of K is a factor of M, and all the factors of M are all possible minimum public multiples, however, N, M <= 1000, therefore, the maximum number of factors within 1000 is 35. Therefore, you only need to record the number and use the discretization method to solve the problem.
# Include <stdio. h> # include <string. h> const int MOD = 1e9 + 7; int dp [2] [1005] [1005]; int LCM [1005] [1005], N, M, K, num [105], cet; int gcd (int a, int B) {if (B = 0) return a; return gcd (B, a % B );} int lcm (int a, int B) {return (a * B)/gcd (a, B);} int main () {for (int I = 1; I <= 1000; I ++) for (int j = 1; j <= 1000; j ++) LCM [I] [j] = lcm (I, j ); while (scanf ("% d", & N, & M, & K )! = EOF) {cet = 0; for (int I = 1; I <= M; I ++) if (M % I = 0) num [++ cet] = I; for (int I = 0; I <= N; I ++) // and for (int j = 1; j <= cet; j ++) // the smallest public multiple dp [0] [I] [num [j] = 0; dp [0] [0] [1] = 1; int flag = 0, ss, ff; for (int k = 1; k <= K; k ++) {flag ^ = 1; for (int I = k; I <= N; I ++) for (int j = 1; j <= cet; j ++) dp [flag] [I] [num [j] = 0; for (int s = K-1; s <= N; s ++) // The number of K-1 must be at least for K-1 (int c = 1; c <= cet; c ++) // Each minimum public multiple {if (dp [flag ^ 1] [s] [num [c] = 0) continue; for (int I = 1; I <= c Et; I ++) // each factor {ss = s + num [I]; ff = LCM [num [c] [num [I]; if (ss> N | M % ff! = 0) continue; dp [flag] [ss] [ff] + = dp [flag ^ 1] [s] [num [c]; dp [flag] [ss] [ff] % = MOD ;}} printf ("% d \ n", dp [flag] [N] [M]);}