• 力扣刷题计划-动态规划-整数拆分


    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 };

       

  • 相关阅读:
    过滤器,拦截器,监听器的区别
    Spring中的@Transactional(rollbackFor = Exception.class)属性详解
    java进阶知识--JAVA锁
    java进阶知识--23种设计模式
    java进阶知识--初识Jedis
    java进阶知识--初识redis
    java进阶知识--Nginx安装与部署
    java进阶知识--Nginx代理
    Linux常用命令
    Linux权限管理
  • 原文地址:https://www.cnblogs.com/hosseini/p/15062542.html
Copyright © 2020-2023  润新知