Leetcode - Dynamic Programming - 343. Integer Break(划分整数得到最大乘积)

1. Problem Description

Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

 

For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).

 

Note: You may assume that n is not less than 2 and not larger than 58.

给你一个整数num2<=num<=58),把这个数划分成几个数的和,求这几个数的乘积的最大值。


2. My solution1(回溯法,超时)

最好想的方法,把这个数划分成从2num个数(记为cnt),并且分别枚举cnt个数分别会是什么,把他们求一下乘积,计算最大值即可。

 

可想而知这种方法必然会超时,不过我们可以利用它来找出规律。


class Solution
{
public:
    int ans;
    void dfs(int num,int cnt,int curproduct)
    {
        if(cnt==1)
        {
            if(curproduct*num>ans)
                ans=curproduct*num;
            return ;
        }
        for(int i=1; i<=num; i++)
            dfs(num-i,cnt-1,curproduct*i);
    }
    int integerBreak(int n)
    {
        ans=1;
        for(int cnt=2; cnt<=n; cnt++)
            dfs(n,cnt,1);
        return ans;
    }
};


3. My solution2(DP) 

利用solution1打印出前23个结果后我发现:

Num integerBreak(num)

2 1

3 2

4 4

5 6

6 9

7 12

8 18

9 27

10 36

11 54

12 81

13 108

14 162

15 243

16 324

17 486

18 729

19 972

20 1458

21 2187

22 2916

23 4374

 

得到的结果必然是多个32的乘积。

 

于是我想到这样的状态转移方程:dp[i]=max(dp[i-3]*3,dp[i-2]*2)

 

当然num<=6时,我们不可以用这种方法求解,因为此时num本身可以被分解成单个或两个23的乘积。

12比较特殊,他们只能分解成1.

3只能分解成21

4=2+2

5=2+3

6=3+3

因为我们至少要把这个数分解成2个数,但是4,5,6最多也就分解成两个“23”的和了,如果用之前的数组求解,还不如把他们自己得到的23求乘积的值大。

所以1~6我们都特殊判定一下,之后的数,至少都可以分解成3个“23”的和,用前面得到的dp值求解就可以了。

class Solution
{
private:
   int dp[60];
public:
    int integerBreak(int n)
    {
      dp[1]=1,dp[2]=1,dp[3]=2,dp[4]=4,dp[5]=6,dp[6]=9;
      for(int i=7;i<=n;i++)
         dp[i]=max(dp[i-3]*3,dp[i-2]*2);
      return dp[n];
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值