題目描述:
蒜頭君覺得白色的牆面好單調,他決定給房間的牆面塗上顏色。他買了 3 種顏料分別是紅、黃、藍,然後把房間的牆壁豎直地劃分成 n 個部分,蒜頭希望每個相鄰的部分顏色不能相同。他想知道一共有多少種給房間上色的方案。
例如,當 n=5 時,下面就是一種合法方案。
|藍|紅|黃|紅|黃|
由於牆壁是一個環形,所以下面這個方案就是不合法的。
|藍|紅|黃|紅|黃|藍|
輸入格式
一個整數 n,表示房間被劃分成多少部分。(1≤n≤50)
輸出格式
一個整數,表示給牆壁塗色的合法方案數。
樣例輸入
4
樣例輸出
18
解題思路:
注意:dp[i]代表一共有i個部分的牆,一共有幾個方案去給牆塗顏色
(1)首先給dp數組初始化,比如有1部分的牆時的方案數,有2個部分的牆的方案數,有3個部分的牆的方案數。dp[1]=3,dp[2]=6,dp[3]=6;
(2)找出遞推式:dp[i]=dp[i-1]+2*dp[i-2];
對於(2)的解釋如下:
一共有i個部分的牆
①第i-1個部分的牆和第1部分的牆顏色不同,(這個時候第i個部分的牆既不能和第1個部分的牆顏色一樣,也不能和第i-1個部分的牆顏色一樣),所以第i個部分的牆的顏色已然確定,只有一種,所以dp[i]=dp[i-1];
②第i-1個部分的牆和第1部分的牆顏色相同,(這個時候第i-2個部分的牆不能和第1以及第i-1個部分的牆顏色一樣),所以第i個部分的牆的顏色有兩種dp[i]=2dp[i-2];【注意:在dii-2個部分的牆的顏色確定的情況下,第i個部分的牆的顏色有兩種方案,所以最終的結果是2dp[i-2]】
所以,dp[i]=dp[i-1]+2dp[i-2];
AC代碼:
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
long long dp[55];
int main()
{
int i,n;
cin>>n;
// dp[i]:一共有i個部分的牆,一共有幾個方案去給牆塗顏色
dp[1]=3;
dp[2]=6;
dp[3]=6;
for(i=4;i<=n;i++)
dp[i]=dp[i-1]+2*dp[i-2];
cout<<dp[n]<<endl;
return 0;
}