信息学奥赛一本通 1196:踩方格 | OpenJudge NOI 2.6 4982:踩方格

【题目链接】

ybt 1196:踩方格
OpenJudge NOI 2.6 4982:踩方格

【题目考点】

1. 递推

【解题思路】

  • 递推状态
    这里用左,右,上 代替 东,西,北。
    l i l_i li为第i步向左走的走法数量
    r i r_i ri为第i步向右走的走法数量
    u i u_i ui为第i步向上走的走法数量
    f i f_i fi为第i步的总走法数量,有 f i = l i + r i + u i f_i=l_i+r_i+u_i fi=li+ri+ui

  • 初始状态
    第0步走法:第0步不走,也算1种走法: f 0 = 1 f_0=1 f0=1
    第1步走法: l 1 = r 1 = u 1 = 1 l_1=r_1=u_1=1 l1=r1=u1=1 f 1 = 3 f_1=3 f1=3

  • 递推关系
    当前是第i步,考虑第i-1步的走法如何影响第i步的走法。

  1. 只有第i-1步是向左或上走时,第i步才能向左走。(因为如果之前是向右走的,现在此处左边是一个已经走过的坍塌的格子。)
    因而现在第i步向左走的走法数量是第i-1步向左和向上走法数量的加和。有: l i = l i − 1 + u i − 1 l_i=l_{i-1}+u_{i-1} li=li1+ui1
  2. 只有第i-1步是向右或向上走时,第i步才能向右走。有: r i = r i − 1 + u i − 1 r_i=r_{i-1}+u_{i-1} ri=ri1+ui1
  3. 无论之前怎么走,第i步都能向上走。有: u i = l i − 1 + r i − 1 + u i − 1 u_i=l_{i-1}+r_{i-1}+u_{i-1} ui=li1+ri1+ui1
    第i步的总走法为第i-1步向上,向左,向右走法的加和
    f i = l i + r i + u i = l i − 1 + u i − 1 + r i − 1 + u i − 1 + l i − 1 + r i − 1 + u i − 1 = 2 ( l i − 1 + u i − 1 + r i − 1 ) + u i − 1 f_i=l_i+r_i+u_i=l_{i-1}+u_{i-1}+r_{i-1}+u_{i-1}+l_{i-1}+r_{i-1}+u_{i-1}=2(l_{i-1}+u_{i-1}+r_{i-1})+u_{i-1} fi=li+ri+ui=li1+ui1+ri1+ui1+li1+ri1+ui1=2(li1+ui1+ri1)+ui1
    已知: f i − 1 = l i − 1 + u i − 1 + r i − 1 f_{i-1} = l_{i-1}+u_{i-1}+r_{i-1} fi1=li1+ui1+ri1 u i − 1 = l i − 2 + r i − 2 + u i − 2 = f i − 2 u_{i-1}=l_{i-2}+r_{i-2}+u_{i-2}=f_{i-2} ui1=li2+ri2+ui2=fi2
    所以: f i = 2 f i − 1 + f i − 2 f_i=2f_{i-1}+f_{i-2} fi=2fi1+fi2

【题解代码】

解法1:以第i步总走法数量为状态
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n, f[25];
	cin >> n;
	f[0] = 1, f[1] = 3;
	for(int i = 2; i <= n; ++i)
		f[i] = 2*f[i-1] + f[i-2];
	cout << f[n];
	return 0;
}
解法2:以第i步向左、右、上方向走法数量为状态
#include <bits/stdc++.h>
using namespace std;
#define N 25
int main()
{
	int n, l[N], r[N], u[N];
	l[1] = r[1] = u[1] = 1;
	cin >> n;
	for(int i = 2; i <= n; ++i)
	{
	    l[i] = l[i-1] + u[i-1];
	    r[i] = r[i-1] + u[i-1];
	    u[i] = l[i-1] + r[i-1] + u[i-1];
    }
	cout << l[n] + r[n] + u[n];
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值