【遞推型 dp】C002_LC1_柵欄染色(爬樓梯變形 / 滾動壓縮)

一、Problem

我們有一個柵欄,它有n個柱子,現在要給柱子染色,有k種顏色可以染。
必須保證不存在超過2個相鄰的柱子顏色相同,求有多少種染色方案。

輸入: n=3, k=2  
輸出: 6
Explanation:

      post 1,   post 2, post 3
way1    0         0       1 
way2    0         1       0
way3    0         1       1
way4    1         0       0
way5    1         0       1
way6    1         1       0

二、Solution

方法一:dp

  • 定義狀態
    • f[i]f[i] 表示染完前 ii 個柵欄的可行方案數
  • 思考初始化:
    • f[0]=kf[1]=k2f[0] = k、f[1] = k^2,爲什麼是 k2k^2 而不是 k×(k1)k × (k-1),其實是的,但是不要忘記 f[i]f[i] 的含義是:染完前 22 個柵欄的可行方案數,所以 f[1]=k×(k1)+f[0]=k2k+k=k2f[1] = k × (k-1) + f[0] = k^2 - k + k = k^2
  • 思考狀態轉移方程
    • f[i]=f[i1)×(k1)+f[i2]×(k1)==(f[i1]+f[i2])×(k1))f[i] = f[i-1) × (k-1) + f[i-2] × (k-1) == (f[i-1] + f[i-2]) × (k-1))
  • 思考輸出f[n1]f[n-1]
public class Solution {
    public int numWays(int n, int k) {
        if (n == 1) return k;
        if (n == 2) return k*k;
        
    	int f[] = new int[n];
    	f[0] = k;
    	f[1] = k*(k-1) + f[0];
    	for (int i = 2; i < n; i++) {
    		f[i] = (f[i-1] + f[i-2])  × (k-1);
    	}
    	return f[n-1];
    }
}

複雜度分析

  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(n)O(n)

方法二:空間壓縮

染到第 i 個柵欄的方案數之和前 i-1 和前 i-2 個有關,所以只需要狀態轉移之後,交換一下 f[i]、f[i-1]、f[i-2] 的位置即可…


複雜度分析

  • 時間複雜度:O()O()
  • 空間複雜度:O()O()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章