Paint Fence
There is a fence with n posts, each post can be painted with one of the k colors.
You have to paint all the posts such that no more than two adjacent fence posts have the same color.
Return the total number of ways you can paint the fence.
Note:
n and k are non-negative integers.
DP
复杂度
O(N) 时间 O(1) 空间
思路
如图,假设当前要计算第三个格子(表示前三个格子共有几种涂色数),在即将开始计算的这个时刻,有两个变量:
same:表示前两个颜色一样的的涂色数
diff:表示前两个颜色不一样的涂色数
注意在这个时刻,第二个格子的涂色总数为此刻same + diff的值
要得到第三个格子(dp[3],表示前三个格子的涂色数,下同)的涂色数,需要新的same'和diff',第三个格子的涂色数为same'+diff',和第二个格子的涂色数计算方法如出一辙
此时此刻,面临着两种情况:
前两个涂色为same的情况,第三个格子只能选择一个新的颜色,故第三个格子有same * (k-1)种涂色数,这样第二个和第三个格子的数必定不同,记为diff' = same * (k-1)
-
前两个涂色为diff的情况,第三个格子有两种选择:
第三个格子不与第二个格子颜色相同,故这种情况第三个格子有diff * (k - 1)种涂色数,这样第二个和第三个格子的数不同,记为diff'' = diff * (k - 1)
第三个格子与第二个格子颜色相同,故这种情况第三个格子有diff * 1种涂色数,这样第二个和第三个格子的数相同,记为same' = diff * 1
这样我们就得到了新的same' = diff * 1, 新的diff' = diff' + diff'' = (same + diff) * (k - 1)
第i个格子的涂色数就是计算了新的diff'和same'之后,二者的和,即same'+diff'
注意
注意这题的规则是最多相邻两个相同!
代码
public class Solution {
public int numWays(int n, int k) {
if (n <= 0)
return 0;
if (n == 1)
return k;
if (n == 2)
return k * k;
int same = k;
int diff = k * (k - 1);
int result = 0;
for (int i = 3; i <= n; i++) {//i表示第几个栅栏涂色总数,共n个,从1开始
int tmp = diff;
diff = (same + diff) * (k - 1);
same = tmp;
result = diff + same;
}
return result;
}
}