来源:力扣 (LeetCode)
链接:https://leetcode-cn.com/problems/paint-fence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一、题目描述
有 k 种颜色的涂料和一个包含 n 个栅栏柱的栅栏,每个栅栏柱可以用其中一种颜色进行上色。
你需要给所有栅栏柱上色,并且保证其中相邻的栅栏柱 最多连续两个 颜色相同。然后,返回所有有效涂色的方案数。
注意:n 和 k 均为非负的整数。
示例
- 输入:n = 3,k = 2
- 输出:6
- 解析:用 c1 表示颜色 1,c2 表示颜色 2,所有可能的涂色方案有:
|
1 2 3 4 5 6 7 8 |
柱 1 柱 2 柱 3 ----- ----- ----- ----- 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 标注是简单题目,但是对我这种脑袋不太灵光的人来说,并不太简单,所以多参考了几种解题思路。
2.1 递推
假设前一个栅栏的颜色数量为 f(n - 1),再前一个栅栏的颜色数量为 f(n - 2 。
递推的思路:
- 如果当前栅栏颜色和前一个栅栏颜色一样,它的选择是
k - 1(因为当前栅栏和前一个栅栏颜色一样,所以前一个栅栏颜色和更前一个展览的颜色不能一样,少一种颜色选择),这种情况的颜色数量为f(n - 2) * (k - 1)。 - 如果当前栅栏颜色和前一个栅栏颜色不一样,那么当前栅栏的颜色选择就只有
k - 1种,总的颜色数量为f(n - 1) * (k - 1)。
总结出来的递推公式:f(n) = f(n - 1) * (k - 1) + f(n - 2) * (k - 1)。
代码:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Solution { public: int numWays(int n, int k) { int prev, pprev, rs, i; if (n <= 0 || k <= 0) return 0; if (n == 1) return k; pprev = k; prev = k * k; rs = prev; for (i = 2; i < n; i++) { rs = pprev * (k - 1) + prev * (k - 1); pprev = prev; prev = rs; } return rs; } }; |
2.2 动态规划
以前面两个栅栏的颜色来确定当前栅栏的颜色:
- 如果前两个栅栏的颜色相同,那么当前栅栏的颜色有 k - 1 种。
- 如果前两个栅栏的颜色不同,那么当前栅栏的颜色有 k 种。
分别以 dp1 和 dp2 保存颜色相同和不同的种数,可以总结出来的状态转移方程:
- dp1 = prev_dp1
- dp2 = (k - 1) * (dp1 + dp2)
dp1 是相同的颜色数量,它和上一个栅栏颜色相同,所以就等于上一个栅栏颜色数量。 dp2 是不同的颜色数量,它等于上一个栅栏颜色总量的和乘以 k - 1 。
代码:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Solution { public: int numWays(int n, int k) { int dp1, dp2, rs, i; if (n <= 0 || k <= 0) return 0; if (n == 1) return k; dp1 = k; dp2 = k * (k - 1); for (i = 2; i < n; i++) { rs = (dp1 + dp2) * (k - 1); dp1 = dp2; dp2 = rs; } return dp1 + dp2; } }; |
![[leetcode]276-栅栏涂色](https://www.dyxmq.cn/wp-content/uploads/2020/02/532ce-image57287b3fd0fa77e2.md.png)
![【每日打卡】[leetcode+剑指offer] 169-多数元素](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/03/d3450-image.png&w=280&h=210&a=&zc=1)
![[leetcode]1030-距离顺序排列矩阵单元格](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/02/d43fb-imagea0be8088e44c8b7a.png&w=280&h=210&a=&zc=1)
![[leetcode]198-打家劫舍](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/02/b1e35-image.png&w=280&h=210&a=&zc=1)
![【每日打卡】[leetcode]面试题1.6-字符串压缩](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/03/776bc-image.png&w=280&h=210&a=&zc=1)

![[leetcode]199-二叉树的右视图](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/04/f24a8-image.png&w=280&h=210&a=&zc=1)
![【每日打卡】[leetcode]72-编辑距离](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/04/88c60-imageff84a6c5047db6ed.png&w=280&h=210&a=&zc=1)
![【每日打卡】[leetcode]460-LFU缓存](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/04/5b3f2-image.png&w=280&h=210&a=&zc=1)
![[leetcode]125-验证回文串](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/03/5bfa5-image.png&w=280&h=210&a=&zc=1)
![【每日打卡】[程序员面试宝典]17.16-按摩师](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/03/9ecc9-image.png&w=280&h=210&a=&zc=1)
![【每日打卡】[leetcode]876-链表的中间节点](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/03/64d0d-imagece778ab033c9d90d.png&w=280&h=210&a=&zc=1)
![【每日打卡】[剑指offer]面试题40-最小的k个数](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/03/c83c9-imagec745c425c670e18c.png&w=280&h=210&a=&zc=1)
![【每日打卡】[leetcode]-409最长回文子串](https://www.dyxmq.cn/wp-content/themes/begin/prune.php?src=https://www.dyxmq.cn/wp-content/uploads/2020/03/e5589-image788d511d7c1e839c.png&w=280&h=210&a=&zc=1)
评论