我的博客頁:https://www.scriptboy.cn/198.htmlhtml
出處:藍橋杯c++
題目描述:eclipse
X國的一段古城牆的頂端能夠當作 2*N個格子組成的矩形(以下圖所示),現須要把這些格子刷上保護漆。ide
你能夠從任意一個格子刷起,刷完一格,能夠移動到和它相鄰的格子(對角相鄰也算數),但不能移動到較遠的格子(由於油漆未乾不能踩!)
好比:a d b c e f 就是合格的刷漆順序。
c e f d a b 是另外一種合適的方案。
當已知 N 時,求總的方案數。當N較大時,結果會迅速增大,請把結果對 1000000007 (十億零七) 取模。spa
輸入:.net
輸入數據爲一個正整數(不大於1000)code
輸出:htm
輸出數據爲一個正整數。blog
樣例輸入:seo
|
2
3
22
|
樣例輸出:
|
24
96
359635897
|
思路:
固定起點,因爲若是起點在中間(第2~N-1列)能夠分爲左右兩邊來討論,這時起點都是角格子。假如
a[i]
表示2*i
的格子從左上角開始刷刷完全部格子的方案數(其中i表示列數,1<=i<=N
),有三種刷法刷完全部格子:
- 先向下刷(即先刷左下角),向下刷完以後有兩種方法跳到下一列,刷完剩下的
i-1
列須要2*a[i-1]
;- 向下一列刷,最後刷左下角,能夠看出不能同列刷,只能一直向右刷,且在沒有到最後一列以前是不能返回,因此刷完全部格子有2^i個方案;(此種狀況比較特殊,後面須要還要用到,因此單獨用
b[i]
存儲下來)- 向下一列刷,有兩種方案到下一列,而後返回左下角,再刷下一列未刷格子以後,而後有兩種方案再到下一列,可見有四種方案到下下列,因此刷完全部格子有
4*a[i-2]
個方案;總之,就是左下角格子何時刷,形成了不一樣的狀況。若是是起點不在角格子上,不難看出,能夠將左右兩側分割成
2*i
和2*(N-i)
的矩形,須要其中一個矩形使用第2種刷法刷才能回到另外一個矩形中。參考:https://blog.csdn.net/roosevelty/article/details/50706322
AC代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
long long a[1005], b[1005], sum;
int main()
{
int N;
while(cin >> N)
{
sum = 0;
b[1] = 1;
for(int i = 2; i <= N; i++)
{
b[i] = b[i-1] * 2 % mod;
}
a[1] = 1;
a[2] = 6;
for(int i = 3; i <= N; i++)
{
a[i] = b[i] + a[i-2]*4 + a[i-1]*2;
a[i] %= mod;
}
sum += 4*a[N]; // 四個角的狀況
// 中間爲起點的狀況
for(int i = 2; i < N; i++)
{
sum += (2*b[i]*2*a[N-i]+2*a[i-1]*2*b[N-i+1])%mod;
}
if(N == 1) sum = 2;
cout << sum %mod << endl;
}
return 0;
}
|