洛谷题单指南-递推与递归-P1990 覆盖墙壁

原题链接:https://www.luogu.com.cn/problem/P1990

题意解读:用两种可旋转的形状铺满N*2的区域,求方案数,可以使用递推。

解题思路:

步骤1、设f[i]表示铺满i*2的区域的方案数

根据要求,i*2区域最后一列有4种可能的铺法:

如果采用图1铺法,则有f[i] = f[i - 1]

如果采用图2铺法,则有f[i] = f[i - 2]

如果采用图3、图4铺法,由于第i-1列有空隙,无法仅使用f[]实现递推!

因此。。。

步骤2、另设g[i]表示铺满i*2的区域且第i列有一个空白的方案数

最后一列可能的情况:

以图1为例来讨论,最后一列可能的铺设方式有

如果采用图1铺法,则有g[i] = g[i - 1]

如果采用图2铺法,则有g[i] = f[i - 2]

因此,g[i] = g[i - 1] + f[i - 2]

步骤3、再来讨论步骤1中图3、图4的铺法

对于图3、图4,都有有f[i] = g[i - 1]

因此,f[i] = f[i - 1] + f[i - 2] + g[i - 1] * 2

步骤4:初始化

f[1] = 1, f[2] = 2

g[1] = 0, g[2] = 1

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1000005;
int f[N], g[N], n;

int main()
{
    cin >> n;

    f[1] = 1;
    f[2] = 2;
    g[1] = 0;
    g[2] = 1;
    if(n <= 2) 
    {
        cout << f[n];
        return 0;
    }
    for(int i = 3; i <= n; i++)
    {
        f[i] = (f[i - 1] + f[i - 2] + g[i - 1] * 2) % 10000;
        g[i] = (g[i - 1] + f[i - 2]) % 10000;
    }
    cout << f[n];

    return 0;
}

 

posted @ 2024-02-19 15:58  五月江城  阅读(70)  评论(0编辑  收藏  举报