計蒜客CS109習題DP 牆壁塗色

2021-07-31 07:42:27 字數 1007 閱讀 5020

蒜頭君覺得白色的牆面好單調,他決定給房間的牆面塗上顏色。他買了 3

3 種顏料分別是紅、黃、藍,然後把房間的牆壁豎直地劃分成 n

n 個部分,蒜頭希望每個相鄰的部分顏色不能相同。他想知道一共有多少種給房間上色的方案。

例如,當 n = 5n=

5 時,下面就是一種合法方案。

由於牆壁是乙個環形,所以下面這個方案就是不合法的。

乙個整數 n

n,表示房間被劃分成多少部分。(1 \leq n \leq 501≤

n≤50

)乙個整數,表示給牆壁塗色的合法方案數。

不看提示直接用演繹法做,首先暴力dfs想出思路如下:

由於dfs到最後一層第n層的狀態sn需要和第1層的狀態s1比較,所以需要儲存s1。

於是想到 dfs(s1,sk,k);  需要儲存的是第1層狀態s1,當前層數k以及第k層的狀態sk 。

然後因為這題n<50,方案數為3,所以暴搜時間代價為3^50,肯定是跑不出來的。

然後再思考遞推的寫法。開乙個揹包陣列dp[i][j][k] ,

當k!=n時,dp[i][j][k] = dp[i][all(m)][k-1]  (m!=j)

當k==n時,dp[i][j][k]=dp[i][all(m)][k-1]   (m!=j) && (i!=j)

從而也可以看出迴圈的順序,k在最外層,i是第1層狀態,在次外層,之後是當前層狀態j,然後每次dp維護需要遍歷m,所以最內層迴圈為m。

附**:

#includeusing namespace std;

long long dp[3][3][53];

int main(void)

}for(int k=1;k<=n-1;k++)

else{

for(int m=0;m<3;m++){

if(m==j) continue;

dp[i][j][k]+=dp[i][m][k-1];

// cout<

計蒜客CS109DP習題 撿水果

蒜頭在玩一款遊戲,他在乙個山頂,現在他要下山,山上有許多水果,蒜頭每下乙個高度就可以撿起乙個水果,並且獲得水果的能量。山的形狀如圖所示 3 1 2 6 2 3 3 5 4 1 這是乙個高度為 4 4 的山,數字代表水果的能量。每次下乙個高度,蒜頭需要選擇是往左下走,還是往右下走。例如 對於上圖的情況...

計蒜客習題 朋友

在社交的過程中,通過朋友,也能認識新的朋友。在某個朋友關係圖中,假定 a 和 b 是朋友,b 和 c 是朋友,那麼 a 和 c 也會成為朋友。即,我們規定朋友的朋友也是朋友。現在,已知若干對朋友關係,詢問某兩個人是不是朋友。請編寫乙個程式來解決這個問題吧。輸入格式 第一行 三個整數 n,m,p n ...

計蒜客習題 逃跑

一位博主寫了ac 但是無論是廣度bfs還是深度dfs,都會報錯,dfs是執行超時,bfs是答案錯誤。傳送門 另一位博主使用了dfs 有興趣可以看下,沒有檢驗是否正確,傳送門 根據前位博主的bfs 做了幾項修改,然後用自己的 找錯前位博主,發現找不出來,有興趣的小夥伴可以試下,找一下前位博主的錯誤。當...