14 剪绳子

题目

给你一根长度为n绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1)。每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0] * k[1]k[m]可能的最大乘积是多少?例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。

C++题解

方法一

动态规划

class Solution {
public:
	int maxProductAfterCutting(int length)
	{
		if (length < 2)
			return 0;
		if (length == 2)
			return 1;
		if (length == 3)
			return 2;

		int * products = new int[length + 1];
		products[0] = 0;
		products[1] = 1;
		products[2] = 2;
		products[3] = 3;

		int max = 0;
		for (int i = 4; i <= length; ++i)
		{
			max = 0;
			for (int j = 1; j <= i / 2; j++)
			{
				int product = products[j] * products[i - j];
				if (max < product)
					max = product;

				products[i] = max;
			}
		}

		max = products[length];
		delete[] products;

		return max;
	}
};

方法二

贪婪算法:
当n大于等于5时,我们尽可能多的剪长度为3的绳子;当剩下的绳子长度为4时,把绳子剪成两段长度为2的绳子。 为什么选2,3为最小的子问题?因为2,3包含于各个问题中,如果再往下剪得化,乘积就会变小。 为什么选长度为3?因为当n≥5时,3(n−3)≥2(n−2)3(n−3)≥2(n−2)
效率分析:
动态规划:空间复杂O(n),时间复杂\(O({n^2})\)
贪婪算法:空间时间均为O(1)。

class Solution {
public:
    int maxProductAfterCutting(int n) 
    {
        if (n <= 3) 
            return 1 * (n - 1);
            
        int res = 1;
        if (n % 3 == 1) 
            res = 4, n -= 4;
        else if (n % 3 == 2) 
            res = 2, n -= 2;
            
        while (n) 
            res *= 3, n -= 3;
            
        return res;
    }
};

python 题解

方法一

动态规划

class Solution:
    def maxProductAfterCutting(self, n):
        # 动态规划
        if n<2:
            return 0
        if n==2:
            return 1
        if n==3:
            return 2
        products=[0]*(n+1)
        products[0]=0
        products[1]=1
        products[2]=2
        products[3]=3

        for i in range(4,n+1):
            max=0
            for j in range(1,i//2+1):
                product=products[j]*products[i-j]
                if product>max:
                    max=product
            products[i]=max
        #print(products)
        return products[n]

方法二

贪婪算法

class Solution:
    def maxProductAfterCutting(self, n):
        # 贪婪算法
        if n < 2:
            return 0
        if n==2:
            return 1
        if n==3:
            return 2
        timesOf3 = n//3
        if n - timesOf3*3 == 1:
            timesOf3 -= 1
        
        timesOf2 = (n - timesOf3 * 3)//2
        return (3**timesOf3) * (2**timesOf2)
posted @ 2019-02-27 08:28  youngliu91  阅读(124)  评论(0编辑  收藏  举报