音乐播放器
chu_K's blog
 
文章 标签
22 9

Powered by Gridea | Theme: Fog
载入天数...
载入时分秒...
御风飞行中...

【OI】题解AT4787 [ABC129C] Typical Stairs

思路:

首先看到题目就会想到一道与这题十分相似的题,应该是叫爬楼梯
两题唯一不同的就是本题多出了一项条件:第 a1,a2...ama_1,a_2...a_m 个台阶是不能走的。

那么这题就和爬楼梯一样,是一个简单 dpdp

首先我们定义 fif_i 表示到第 ii 阶台阶的方案数,因为每次只能上一层或两层,所以状态转移方程也很好推:fi=fi1+fi2f_i=f_{i-1}+ f_{i-2} 又因为第 a1,a2...ama_1,a_2...a_m 个台阶不能走,所以我们要定义一个 boolbool 数组,若 ffai=trueff_{a_i}=true 则不进行操作,且若连续的两阶台阶都不能走的话就可以直接输出 00 因为无法走到顶。

知道大致思路后这题还有两个需要注意的小细节

  1. 在进行状态转移时别忘了取模。
  2. 若第一阶和第二阶台阶均可走 f2=2f_2=2 若只有第二阶可走则 f2=1f_2=1
    (刚做时我也做错了)

CODE

#include <cstdio>
#include <iostream>
#define int long long
using namespace std;
int i,n,f[1000001],j,m,a,sum;
bool ff[1000001];
const int mod = 1000000007;
signed main()
{
        cin >> n >> m;
        for (i=1; i<=n; i++) {ff[i]=true; f[i]=0;}
        for (i=1; i<=m; i++) {cin >> a; ff[a]=false;}

        if (ff[1]) f[1]=1; if (ff[2]&&ff[1]) f[2]=2; else if (ff[2]) f[2]=1;

        for (i=3; i<=n; i++)
        {
                if (ff[i-1]==false&&ff[i-2]==false) {cout << 0; return 0;}
                if (ff[i-1]==false&&ff[i]==false) {cout << 0; return 0;}
                if (ff[i]) f[i]=(f[i-2]+f[i-1]) % mod;
        }
        sum=f[n]% mod;
        cout << sum << endl;
}

再来一份Pascal的伪代码:

          if ff[1]=true then f[1]:=1;
          if (ff[2]=true) and (ff[1]=true) then f[2]:=2
                           else if (ff[2]=true)  then f[2]:=1;

        for i:=3 to n do
        begin 
        if (ff[i-1]=false) and (ff[i-2]=false) then 
           begin
              write(0);exit;end;
        if (ff[i-1]=false) and (ff[i]=false) then
           begin
              write(0);exit;end;
          if (ff[i]=true) then 
                 f[i]:=f[i-2]+f[i-1] mod 1000000007; 
        end; 

八格缩进有点难看请见谅。