[Luogu p1192] level problem

Portal

Step problem

Title Description

There \ (N \) grade level, you start at the bottom, each can step up at most \ (K \) of steps (a minimum of \ (1 \) level), ask to reach the first \ (N \) of steps have how many different ways.

Input and output formats

Input Format

Two positive integers N, K.

Output Format

A positive integer, the number of different ways, because the answer may be large, you need to output \ (ans bmod \ 100003 \) results after.

Sample input and output

Input Sample # 1

5 2

Sample Output # 1

8

Explanation

For \ (20 \% \) data, there are \ (N ≤ 10, K ≤. 3 \) ;
for \ (40 \% \) of data, there are \ (N ≤ 1000 \) ;
for \ (100 \% \) data, there are \ (N ≤ 100000, K ≤ 100 \) .

analysis

This is a recursive problem. Encounter this problem, apart from anything else scratch to find the law.
Let's look at \ (k \) results for different values of time:

k = 2: 1 2 3 5 8 13 21 34 55
k = 3: 1 2 4 7 13 24 44 81 149
k = 4: 1 2 4 8 15 29 56 108 208
k = 5: 1 2 4 8 16 31 61 120 236
k = 6: 1 2 4 8 16 32 63 125 248

Set \ (dp_i \) is climbing \ (I \) -step answer, then we can get a rule:
When \ (n \ le k \) when, \ (dp_i = 2 ^ {I-. 1} \ )
when (n> k \) \ time, \ (dp_i = \ J = I sum_ {-} ^ {K} I-dp_j. 1 \) .
How to prove? First, assume \ (n-=. 5, K = 2 \) , then climb up to two levels. At this time, there is a climb case 1, there are two kinds of two climbing situation. Then climb three it? We can climb three first climb and then climb two level, or to climb a climb two (but must then climb the two-time climbed, otherwise the program will be in front of, first climb and then climb 2 1 repeat). Then climbing method number three is the number of climbing method stage 1 plus the number of stage 2 climbing method, that is, 1 + 2 = 3. Similarly climb four levels, we can first climb and then climb a three, or you can climb two to climb two (the same token, it must be two at once.) The end result is the number of ways to climb three plus number of two climbing method, that is 2 + 3 = 5. And so on, each level method of the first two numbers are and.
Then a maximum of three it? Level 1 is now determined to climb the answer 1, Level 2 Answer 2 climb, climb three answer 4. Then climb level 4 case, it is to first climb and then climb a three, the first climb and then climb two levels, first climb a climb three. Then, climb four way number is the number of ways of the first stage plus the second stage numbers method is a method of adding a third pole. And so, a number of methods per class and are the first three.
Up to four Similarly, up to five, too, we have successfully demonstrated several methods a level equal before \ (k \) number of class and method.
But this is\ (n> k \) case, but \ (n = k \) when the result is \ (K-2. 1 ^ {} \) . What is the matter with this? First, we know that there is a theorem \ (^ 2 ^. 1 + 0 + 2 + 2 ^ 2 \ ldots + ^ {n-2}. 1 + 2-n-^ = ^ {n-2} + -1. 1 \) . For example, if the input data at this time is \ (the n-3 =, k = 3 \) , first of all we would like if \ (k = 2 \) , the answer is the former two together. This time is \ (2 ^ 2 ^ 0 + 1 \) . But when \ (k = 3 \) , we will add here a solution: a direct step by step in the past. This time the answer is \ (2 ^ 2 ^ 0 + 1 + 1 \) , and according to the previous theorem, this is the \ (2 ^ 2 \) .

From the particular to the general, if the input data is \ (= n-P, P K = \) , we must first think if \ (K = P -. 1 \) , before the answer is \ (p-1 \) a series and a number of methods, i.e. \ (^ 2 ^. 1 + 0 + 2 + 2 ^ 2 \ ldots + 2 P-2 ^ {} \) , but this time \ (K = P \) . We can step directly in the past, the answer would have \ (+ 1 \) , that is, \ (2 ^ 0 + 1 + 2 ^ 2 ^ 2 + \ ldots + 2 ^ {2}-the p-+1 \) , namely \ ( . 1-P ^ {2} \) . That is, \ (n-K = \) when the answer is \ (K-2. 1 ^ {} \) .
Ba Baba so much code directly in accordance with the above formula to push thousand million. Time complexity \ (O (NK) \) .
But this is something else, there is room for optimization of this stuff. Seeking section and with the prefix and is a good way to look at this equation: When \ (n> k \) when, \ (dp_i = \ sum_ {J = I - K} ^ {I-. 1} dp_j \) . We can deduce about the soul:
$$ \ the begin {aligned}
dp_i & = \sum_{j = i - k}^{i - 1}dp_j\ & = \sum_{j = i - k}^{i - 2}dp_j + dp_{i - 1}\ &= \sum_{j = i - k - 1}^{i - 2}dp_j + dp_{i - 1} - dp_{i - k - 1} \ & = dp_{i - 1} + dp_{i - 1} - dp_{i - k - 1} \ & = 2\times dp_{i - 1} - dp_{i - k - 1}

\end{aligned}
$$

Ever since, the algorithm will become a \ (O (the n-) \) .

Code

Plain \ (O (nk) \) algorithm:

/*
 * @Author: crab-in-the-northeast 
 * @Date: 2020-02-28 16:18:47 
 * @Last Modified by: crab-in-the-northeast
 * @Last Modified time: 2020-02-28 16:24:45
 */
#include <iostream>
#include <cstdio>

int n,k;
int dp[100005];
const int mod = 100003;

int main() {
    scanf("%d%d",&n,&k);
    dp[1] = 1;
    for(int i = 2; i <= k; i++)
        dp[i] = dp[i - 1] * 2 % mod;
    for(int i = k + 1; i <= n; i++)
        for(int j = i - k; j < i; j++)
            dp[i] += dp[j] % mod;
    printf("%d\n",dp[n] % mod);
    return 0;
}

Clever \ (O (n) \) practices:

/*
 * @Author: crab-in-the-northeast 
 * @Date: 2020-02-28 16:18:47 
 * @Last Modified by: crab-in-the-northeast
 * @Last Modified time: 2020-03-01 23:28:48
 */
#include <iostream>
#include <cstdio>

int n,k;
int dp[100005];
const int mod = 100003;

int main() {
    scanf("%d%d",&n,&k);
    dp[0] = dp[1] = 1;
    for(int i = 2; i <= k; i++)
        dp[i] = dp[i - 1] * 2 % mod;
    for(int i = k + 1; i <= n; i++)
        dp[i] = (dp[i - 1] * 2 - dp[i - k - 1])% mod;
    printf("%d\n",(dp[n] + mod) % mod);
    return 0;
}

Evaluation results

AC 100, plain \ (O (nk) \) practice: R31166063
AC 100, recursive \ (O (n) \) practice: R31278504

Guess you like

Origin www.cnblogs.com/crab-in-the-northeast/p/luogu-p1192.html