Leetcode 276.栅栏涂色

Time: 20190904
Type: Easy
考察:动态规划

题目描述

有 k 种颜色的涂料和一个包含 n 个栅栏柱的栅栏,每个栅栏柱可以用其中一种颜色进行上色。

你需要给所有栅栏柱上色,并且保证其中相邻的栅栏柱 最多连续两个 颜色相同。然后,返回所有有效涂色的方案数。

注意:
n 和 k 均为非负的整数。

示例:

输入: n = 3,k = 2
输出: 6
解析: 用 c1 表示颜色 1c2表示颜色 2,所有可能的涂色方案有:

123     
 -----      -----  -----  -----       
   1         c1     c1     c2 
   2         c1     c2     c1 
   3         c1     c2     c2 
   4         c2     c1     c1  
   5         c2     c1     c2
   6         c2     c2     c1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/paint-fence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

定义状态,用f[i]表示从左到有走到下标为i的栅栏时的涂色总数,显然f[0] = kf[1] = k * kf[2] = k * k * k - k

状态迁移方程:

分成两种情况来思考:

  • 当前栅栏颜色和前一个颜色相同,则表示更前一个栅栏颜色和右边两个不同,到更前一个栅栏的涂色方案有f(i-2)种,后面两个涂色相同,共k-1
  • 当前栅栏颜色和前一个不同,则当前栅栏涂色方案有k-1种,到前一个栅栏为止,涂色方案有f(i-1)

所以递推公式是:f[i] = (k - 1) * f[i-1] + (k - 1) * f[i-2]

代码

class Solution:
    def numWays(self, n: int, k: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return k
        if n == 2:
            return k * k
        f = [0] * n
        f[0] = k
        f[1] = k * k
        
        for i in range(2, n):
            f[i] = f[i-1] * (k - 1) + f[i-2] * (k - 1)
            
        return f[-1]

END.

你可能感兴趣的:(LeetCode)