线性 DP 概述
线性动态规划是算法基础中最常见的一类问题。其核心特点是状态转移只依赖于前一个或前几个状态,状态之间的关系呈线性,通常可用一维或二维数组存储。我们在入门阶段解决的《下楼梯》以及《数字三角形》其实都属于线性 DP,分别对应一维和二维的情况。
下面通过四道经典题目,从状态定义、转移方程到代码实现,系统梳理线性 DP 的解题思路。
台阶问题
题目描述

解题思路
本题可以看作是《下楼梯》问题的加强版。我们按照动态规划的常规步骤来分析:
-
状态表示
dp[i]表示走到第i个台阶的所有方案数。 -
状态转移方程 第
i个台阶的方案数等于从i-1阶到i-k阶的所有方案数之和。由于数据量较大,结果需要对100003取模。注意边界检查,当i-j < 0时需停止循环,避免负下标访问。dp[i] = (dp[i] + dp[i - j]) % 100003; // j 从 1 到 k -
初始化 直接令
dp[0] = 1即可。这相当于站在起点(第 0 阶)有一种方案(不动),后续计算会自动累加。 -
填表顺序 从左往右依次计算。
-
输出结果
dp[n]即为最终答案。
代码实现
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10, MOD = 1e5 + 3;
int n, k;
LL dp[N];
int main() {
cin >> n >> k;
// 初始化:站在第 0 阶算作一种方案
dp[0] = ;
( i = ; i <= n; i++) {
( j = ; j <= k; j++) {
(i - j < ) ;
dp[i] = (dp[i] + dp[i - j]) % MOD;
}
}
cout << dp[n] << endl;
;
}





