【算法】动态规划专题① ——线性DP python-举一反三

时间:2025-02-03 19:30:34

每次可以走一级或者两级或者三级,一共有多少种方案呢?
测试链接 https://www.acwing.com/problem/content/3646/


每次可以向上迈 1∼K 级台阶,答案又是多少呢?
在这里我们给出1-k级台阶的解法


台阶问题 https://www.luogu.com.cn/problem/P1192

题目描述

N N N 级台阶,你一开始在底部,每次可以向上迈 1 ∼ K 1\sim K 1K 级台阶,问到达第 N N N 级台阶有多少种不同方式。

输入格式

两个正整数 N , K N,K N,K

输出格式

一个正整数 a n s ( m o d 100003 ) ans\pmod{100003} ans(mod100003),为到达第 N N N 级台阶的不同方式数。

样例输入

5 2

样例输出

8

提示

  • 对于 20 % 20\% 20% 的数据, 1 ≤ N ≤ 10 1\leq N\leq10 1N10 1 ≤ K ≤ 3 1\leq K\leq3 1K3
  • 对于 40 % 40\% 40% 的数据, 1 ≤ N ≤ 1000 1\leq N\leq1000 1N1000
  • 对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 100000 1\leq N\leq100000 1N100000 1 ≤ K ≤ 100 1\leq K\leq100 1K100

思路分析:

结合上面所学,不难得出:
dp[ i i i] = dp[ i i i - 1] + dp[ i i i - 2] + ······ +dp[ i i i - k k k]
当然,这是 i ≥ k i\geq k ik的情况
对于 i < k i< k i<k:
dp[ i i i] = dp[ i i i - 1] + dp[ i i i - 2] + ······ +dp[0]

题解code

mod = 100003

n, k = map(int, input().split())
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 1
for i in range(2, n + 1):
    res = 0
    for j in range(min(i, k) + 1):
        res += dp[i - j]
    dp[i] = res % mod
print(dp[n])


结合前缀和能更快得出答案
什么?还不会前缀和?
点此跳转 超细致讲解


code:

mod = 100003
n, k = map(int, input().split())
dp = [0] * (n + 1)
dp[0] = 1
pre_sum = [0] * (n + 2)
pre_sum[1] = 1
for i in range(1, n + 1):
    if i <= k:
        dp[i] = pre_sum[i] % mod
    else:
        dp[i] = (pre_sum[i] - pre_sum[i - k]) % mod
    pre_sum[i + 1] = (pre_sum[i] + dp[i]) % mod
print(dp[n])