一、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
- 定义状态:
- 表示染完前 个栅栏的可行方案数
- 思考初始化:
- ,为什么是 而不是 ,其实是的,但是不要忘记 的含义是:染完前 个栅栏的可行方案数,所以
- 思考状态转移方程:
- 思考输出:
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];
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:空间压缩
染到第 i 个栅栏的方案数之和前 i-1 和前 i-2 个有关,所以只需要状态转移之后,交换一下 f[i]、f[i-1]、f[i-2] 的位置即可…
复杂度分析
- 时间复杂度:,
- 空间复杂度:,