【递推型 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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章