[leetcode] 276. Paint Fence 解题报告

 

题目链接:https://leetcode.com/problems/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的问题,对于第i个柱子染什么颜色我们要考虑是否和之前染一样的颜色

1. 如果和i-1染一样的颜色,那么第i-1个柱子就不能和第i-2染一样的颜色

2. 如果和第i-1染不一样的颜色,那么第i个柱子的染色方案数即为 sum(i-1) * (k-1)

也就是为了得到第i个柱子的染色方案,我们需要利用之前的两个状态,一个是i-1和i-2染一样颜色的方案数,另一个是i-1和i-2染不一样颜色的方案数,这样我们需要两个dp数组dp1, dp2分别记录对应的状态

然后考虑两个dp数组的递推公式:

dp1[i] = dp2[i-1],这个表示如果i和i-1染一样的色,那么染色方案为dp2[i-1]

dp2[i] = (dp1[i-1] + dp2[i-1]) * (k-1),表示i和i-1染不一样染色,对于第i-1的每一种染色方案,我们有k-1种颜色可选

初始状态为:

dp1[1] = 0

dp2[1] = k

JAVA 代码如下:

class Solution {
    public int numWays(int n, int k) {
        if(n == 0 || k == 0) return 0;
        int[] dp1 = new int[n+1], dp2 = new int[n+1];
        dp1[1] = 0;
        dp2[1] = k;
        for(int i = 2; i <= n; i++) {
            dp1[i] = dp2[i-1];
            dp2[i] = (dp1[i-1] + dp2[i-1]) * (k-1);
        }
        return dp1[n] + dp2[n];
    }
}

有了上面的基础之后我们还可以考虑状态压缩:

C++代码

class Solution {
public:
    int numWays(int n, int k) {
        if(n==0 || k==0 || (k==1 && n>2)) return 0;
        int same = 0, diff = k, total = k;
        for(int i = 2; i <= n; i++)
        {
            same = diff, diff = (k-1)*total;
            total = same + diff;
        }
        return total;
    }
};

参考: https://leetcode.com/discuss/85147/complete-explanation-o-n-time-o-1-space
 

还有一个进阶的题目:https://leetcode.com/problems/number-of-music-playlists/

思路差不多

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值