【题解】走路
I 题意简述
-
从原点出发,一步只能向右走、向上走或向左走。恰好走 \(N\) 步且不经过已走的点共有多少种走法?
-
多组数据,每行输入一个数 \(N\)。对于每一组测试数据,每行输出一个数,答案对 \(12345\) 取模。
-
对于100%的数据,保证 \(1 \leq N \leq 1000\)。时间限制 \(1\text{s}\),空间限制 \(256\text{MB}\)。
II 分析
设 \(f_i\) 表示第 \(i\) 步之后所在的点有几种可能,\(a_i, b_i, c_i\) 分别表示第 \(i\) 步向上走、向左走,向右走的方案数。那么 \(f_i = a_i + b_i + c_i\).
容易发现,第 \(i - 1\) 步无论走到了哪里,接下来都可以向上走。所以有 \(a_i = f_{i - 1}\).
第 \(i\) 步如果要向左走,那么第 \(i - 1\) 步就只能是向左走或向上走,而不能是向右走,所以有 \(b_i = a_{i - 1} + b_{i - 1}\).
第 \(i\) 步如果要向右走,那么第 \(i - 1\) 步只可以向上或向右走,不能向左走,所以有 \(c_i = a_{i - 1} + c_{i - 1}\).
所以:\(\begin{aligned}f_i &\; = f_{i - 1} + a_{i - 1} + b_{i - 1} + a_{i - 1} + c_{i - 1} \\ &\; = f_{i - 1} + (a_{i - 1} + b_{i - 1} + c_{i - 1}) + a_{i - 1} \\ &\; = f_{i - 1} + f_{i - 1} + a_{i - 1} \\ &\; = 2f_{i - 1} + f_{i - 2}\end{aligned}\)
最后我们再定好范围,本题的递推式即为:\(f_i = 2f_{i - 1} + f_{i - 2} (i \geq 3)\). 按顺序计算即可。
III 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1005, mod = 12345;
int n, f[N];
int main(){
f[1] = 3, f[2] = 7;
for(int i = 3; i <= 1000; i++)
f[i] = (2 * f[i - 1] + f[i - 2]) % mod;
while(scanf("%d", &n) != EOF)
printf("%d\n", f[n]);
return 0;
}