首页 > 技术文章 > 力扣刷题计划-动态规划-整数拆分

hosseini 2021-07-27 09:17 原文

1.原题地址

  343. 整数拆分 - 力扣(LeetCode) (leetcode-cn.com)

2.题目描述:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

示例2:

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

说明:  不小于 2 且不大于 58。

3.分析

动态规划三部曲:

  (1) 首先定义数组,dp[i],i代表需要被拆分的整数,dp[i]代表整数i被拆分后得到的最大乘积

  (2)分析递推公式

  对于整数 i ,i >2,假设 i 被拆分成m1+m2+...+mk得到的乘积最大,可以分析得知 1<k<n+1

  i = m1+m2+...+mk= (m1+m2+...+mk-1)+mk

       对于数字i,至少要被拆分成两个数字记作 i = (i -j) + j,

       对于j = mk不再被拆

       对于( i-j ) = m1+m2+...+mk-1如果被拆则乘积为 i*dp[i-j]如果不被拆则乘积为 i*j

       所以最大乘积为  max ( i*dp[i-j] , i*j )

  (3) 边界

        dp[0] = 0,dp[1] = 0

4.完整代码

 1 class Solution {
 2 public:
 3     int Max(int num1,int num2)
 4     {
 5         return num1>num2 ? num1:num2;
 6     }
 7     int Max(int num1,int num2,int num3)
 8     {
 9         return num3>Max(num1,num2) ? num3:Max(num1,num2);
10     }    
11     int integerBreak(int n) {
12     if(n==2)
13         return 1;
14      int *dp = new int[n+1];
15      dp[0] = 0;
16      dp[1] = 0;
17      dp[2] = 1;
18      for(unsigned i=3;i<n+1;++i)
19      {
20         dp[i] = i-1;
21         for(unsigned j=1;j<i;++j)
22         {
23             dp[i] = Max(dp[i],dp[i-j]*j,(i-j)*j);
24         }
25      }
26      int result = dp[n];
27      delete []dp;
28      return result;
29     }
30 };

 

 

   

推荐阅读