• 276. Paint Fence


    这题有歧义啊。。说的是颜色相同的相邻数量不能超过2个,不是颜色相同的对数不能超过2个,我日了。

    搞懂之后就不难了,动态规划。

    每一次粉刷都有2种可能,和前一个颜色相同;和前一个颜色不同。

    same[i] = diff[i-1];  
    diff[i] = (same[i-1]+diff[i-1]) * (k-1);
    

    总和是same[n]+diff[n]..

    然后,这种一维DP是不需要整个数组的,3个变量就够了,但是这么写更清楚。

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


    二刷。

    还是动态规划,分情况。

    same[i] = diff[i-1];
    diff[i] = (k-1) * (diff[i-1] + same[i-1])

    这次改成单一变量。。

    Time: O(n)
    Space: O(1)

    public class Solution {
        public int numWays(int n, int k) {
            if (n == 0 || k == 0) return 0;
            if (n == 1) return k;
            if (n == 2) return k*k;
            
    
            int same = k;
            int diff = k*(k-1);
            
            // diff[i] = (k - 1) * (diff[i-1] + same[i-1])
            // same[i] = diff[i-1]
            for (int i = 3; i < n + 1; i++) {
                
                int temp = (k - 1) * (diff + same);
                same = diff;
                diff = temp;
            }
            
            return diff + same;
        }
    }
    

    三刷。

    这个题还是挺有意思的。

    一刷二刷的思路是。

    对于第n个房子来说,分成2种情况:
    1.和n-1的颜色一样.
    2.和n-1的颜色不一样.

    前者是dp(n-1)种可能,颜色一样,n-1有多少种可能,n就有多少。
    后者是可选颜色数k-1,因为不一样所以-1,乘以dp[n-1]的可能性。

    按照这个思路做的。

    这次换了个思路,按照rob house的方法考虑。

    三个连起来的房子不能颜色一样,那对于第n个房子来说:要么跟n-1的颜色不一样,要么跟n-2的颜色不一样,要么跟n-1 n-2的颜色都不一样。

    (k-1)*(dp[n-1]) + (k-1) * dp[n-2] 跟1颜色不一样乘以跟2颜色不一样。。里面已经包含跟1跟2都不一样了。。

    public class Solution {
        public int numWays(int n, int k) {
            if (n == 0 || k == 0) return 0;
            if (n == 1) return k;
            if (n == 2) return k*k;
            
            int[] dp = new int[3];
            
            dp[0] = k;
            dp[1] = k*k;
            for (int i = 2; i < n; i++) {
                dp[i%3] = (dp[(i-2)%3] + dp[(i-1)%3]) * (k-1);
            }
            
            return dp[(n-1)%3];
        }
    }
    
  • 相关阅读:
    c#备忘知识点
    [置顶] IE6支持的滑动菜单栏
    摩斯电碼中英文对照表
    2013年5月15日星期三
    2013年5月9日星期四
    2013年5月12日16:20:43母亲节
    2013年5月8日星期三
    JS前端DOM中Range疑问
    2013年5月14日星期二
    2013年5月13日星期一
  • 原文地址:https://www.cnblogs.com/reboot329/p/6127943.html
Copyright © 2020-2023  润新知