nを読み、さまざまな方法がいくつあるかを尋ねます。答えは1e9+7を法とするものです。
分析:この質問は動的計画法です。f[i] [0]が現在完了している最初のi列の解の数を表し、f [i] [1]が最初のi-1列の現在の完了を表し、 i番目の列前の列の解の数を終えた後、f [i] [2]は、最初のi-1列が現在完了し、現在のi番目の列が次のもの。その場合、答えはf[n][0]です。
動的伝達方程式の導出は次のとおりです。
まず、f[i][0]がどの状態から遷移できるかを確認します。
現在そのようなビルディングブロックを配置したい場合、それは明らかにf [i-1] [0]によって再帰的です。そのようなビルディングブロックを配置するとどうなりますか?、つまりf [i-1] [2]によって再帰的です。つまり、i-1番目の列はすでに次の正方形を綴っています。同様に、f [i-1] [1]は再帰的である可能性があります。つまり、そのようなブロックをi番目の列に入れます:、これがすべての場合だと思いますか、実際、これがすべての場合ではなく、最後の場合があります。つまり、このようなブロックを上下にまとめます。f [i-2] [0]によって決定される、は再帰的に取得され、これはすべてのケースの数です。
つまり、f[i][0]の再帰遷移方程式はf[i][0] =(f [i-1] [1] + f [i-1] [2] + f [i -1] [0] + f [i-2] [0])%mod
f [i] [1]の漸化式を見てみましょう。これは、考えるのが簡単です。1つは、このような構成要素を配置することです。
この状況は、f[i-2][0]に基づいて再帰的に取得されます。もう1つの状況は、このようなブロックを配置することです。この状況はf [i-1] [2]に基づいて取得され、f[i][1]はこれら2つの状況から再帰的に取得されます。
つまり、f[i][1]の伝達方程式はf[i][1] =(f [i-2] [0] + f [i-1] [2])%modです。
同様に、f[i][2]の伝達方程式はf[i][2] =(f [i-2] [0] + f [i-1] [1])%modです。
初期化はf[0][0] = 1に設定する必要があり、再帰方程式にはf [i-2] []が含まれるため、i>=2の場合にいくつかの再帰方程式を実行する必要があることに注意してください。 、範囲外を防ぐため
これを分析した後、このトピックのトピックは基本的に分析され、コードは以下に添付されています
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
using namespace std;
const int mod=1e9+7;
const int N=1e7+10;
long long f[N][3];
int main()
{
int n;
scanf("%d",&n);
f[0][0]=1;
for(int i=1;i<=n;i++)
{
f[i][0]=(f[i-1][0]+f[i-1][1]+f[i-1][2])%mod;
if(i>=2)
{
f[i][0]=(f[i][0]+f[i-2][0])%mod;
f[i][1]=(f[i-2][0]+f[i-1][2])%mod;
f[i][2]=(f[i-2][0]+f[i-1][1])%mod;
}
}
printf("%lld",f[n][0]%mod);
return 0;
}