題意
給你一個的方格,問你有多少種方式可以將方格染成黑色和白色的,而且相鄰的方格最多有兩個顏色相同.
分析與解答
(非官方思路,想的比較繁瑣)
首先我們考慮只有一排的方格,定義dp數組如下:
爲前個第染色爲黑色,且第個爲單獨一個黑色的方案數
爲前個第染色爲白色,且第個爲單獨一個白色的方案數
爲前個第染色爲黑色,且第個爲連續兩個黑色的方案數
爲前個第染色爲白色,且第個爲連續兩個白色的方案數
轉移方程如下:
那麼第方格的染色方案數爲
接下來考慮多排的問題.
我們注意到如果第一排出現兩個相同顏色的情況假設爲和,我們考慮第二排這兩個位置的放置方法,如果我們放置任何一個與第一排顏色不同的那麼組成了三個顏色相同的連續的方塊,因此我們必須放置與第一排顏色不同的兩個方塊,同時我們考慮從這兩個位置向兩側延展,那麼位置,必須放置與第一排顏色不同的塊,位置也只能放置與第一排顏色不同的,以此類推,可得如果第一排有兩個連續的相同方塊第二排必須每個都與第一排顏色不同.這種情況下的方案數爲
如果第一排沒有連續兩個顏色相同的,我們按照同樣的推理方法我們可以得到,同一排相鄰兩個顏色必須不同.因此只要確定了第一列的放置就可以推出所有的排列方案,而第一列的放置不受約束,這種情況的方案數爲
綜上,最後的答案爲
代碼
/*************************************************************************
> File Name: 2019_10_20_3.cpp
> Author: z472421519
> Mail:
> Created Time: 2019年10月20日 星期日 17時45分14秒
************************************************************************/
#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#define MAXN 100003
#define LL long long
const LL mod = 1e9 + 7;
using namespace std;
LL mul(LL a,LL b)
{
LL ans=0;
while(b)
{
if(b&1) ans=(ans+a)%mod;
b>>=1;
a=(a%mod+a%mod)%mod;
}
return ans;
}
LL dp[MAXN][3][3];
LL sum[MAXN];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
dp[1][1][1] = dp[1][0][1] = 1ll;
dp[1][1][2] = dp[1][0][2] = 0ll;
sum[1] = 2ll;
for(int i = 2;i <= 100000;i++)
{
dp[i][1][1] = (dp[i - 1][0][1] + dp[i - 1][0][2]) % mod;
dp[i][0][1] = (dp[i - 1][1][1] + dp[i - 1][1][2]) % mod;
dp[i][1][2] = dp[i - 1][1][1] % mod;
dp[i][0][2] = dp[i - 1][0][1] % mod;
sum[i] = (dp[i][1][1] + dp[i][1][2] + dp[i][0][1] + dp[i][0][2]) % mod;
}
//printf("%lld\n",sum[3]);
cout << ((sum[m] - 2 + mod) + sum[n]) % mod;
}