DP 計蒜客-牆壁塗色
阿新 • • 發佈:2021-01-12
技術標籤:演算法與資料結構
蒜頭君覺得白色的牆面好單調,他決定給房間的牆面塗上顏色。他買了 3 種顏料分別是紅、黃、藍,然後把房間的牆壁豎直地劃分成 n 個部分,蒜頭希望每個相鄰的部分顏色不能相同。他想知道一共有多少種給房間上色的方案。
首先建立DP陣列 dp[60][3],dp[i][0]表示第i個位置放置紅色,以此類推。
則如果不考慮牆壁的迴圈性帶來的最後一塊與第一塊的衝突,有如下狀態轉移:
dp[i][1]=dp[i-1][2]+dp[i-1][0];
dp[i][2]=dp[i-1][0]+dp[i-1][1];
dp[i][0]=dp[i-1][ 1]+dp[i-1][2];
現在只需要求出最後一塊與第一塊衝突的方案數,減去該方案數即可。
牆壁染色情況(第一塊染紅色)示意圖如下:
num_0表示每層0的個數,num_1表示每層非0的個數,則有如下狀態轉移:
long long tmp=num_0;
num_0=num_1;
num_1+=tmp*2;
則ans=dp[n][0]+dp[n][1]+dp[n][2]-num_0*3;
AC程式碼:
#include<iostream>
using namespace std;
int main(){
long long dp[60][3]= {0},n;
cin>>n;
dp[1][0]=dp[1][1]=dp[1][2]=1;
for(int i=2;i<=n;i++){
dp[i][1]=dp[i-1][2]+dp[i-1][0];
dp[i][2]=dp[i-1][0]+dp[i-1][1];
dp[i][0]=dp[i-1][1]+dp[i-1][2];
}
long long ans=dp[n][0]+dp[n][1]+dp[n][2];
long long num_0=1,num_1=0;
for(int i=1; i<n;i++){
long long tmp=num_0;
num_0=num_1;
num_1+=tmp*2;
}
ans-=num_0*3;
cout<<ans;
return 0;
}