LeetCode343. 整数拆分

news/2024/10/17 16:21:44/

343. 整数拆分

文章目录

    • [343. 整数拆分](https://leetcode.cn/problems/integer-break/)
      • 一、题目
      • 二、题解
        • 方法一:动态规划
        • 方法改良


一、题目

给定一个正整数 n ,将其拆分为 k正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积

示例 1:

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

示例 2:

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

提示:

  • 2 <= n <= 58

二、题解

方法一:动态规划

好的,让我们按照动态规划的五个步骤来解决这道题目:

步骤一:确认dp数组以及下标的含义

  • dp[i] 表示正整数 i 拆分后可以获得的最大乘积。

步骤二:确认递推公式

  • 对于正整数 i,我们可以把它拆分成两个正整数 j 和 i-j,其中 1 <= j < i。
  • 那么,对于拆分的两个正整数 j 和 i-j,可以计算它们的乘积 max(j * (i-j))。
  • 但我们还需要考虑 j 和 i-j 是否继续拆分,因此递推公式为 dp[i] = max(max(j * (i-j), j * dp[i-j]), max(dp[j] * (i-j), dp[j] * dp[i-j]))。

步骤三:数组初始化

  • dp[1] 和 dp[2] 的值分别为 0 和 1,因为它们都不能再拆分。

步骤四:确定遍历顺序

  • 我们从小到大遍历正整数 i,从 3 开始遍历到 n,依次计算 dp[i] 的值。

步骤五:举例推导dp数组
让我们通过一个示例来推导 dp 数组。假设输入 n = 6:

进行推导:

  1. 初始化 dp 数组:
dp = [0, 1]
  1. 计算 dp[3]:
dp[3] = max(max(1*(3-1), 1*dp[3-1]), max(dp[1]*(3-1), dp[1]*dp[3-1])) = max(max(1*2, 1*1), max(0*2, 0*1)) = 2
  1. 计算 dp[4]:
dp[4] = 4
  1. 计算 dp[5]:
dp[5] = 6
  1. 计算 dp[6]:
dp[6] = 9

最终返回 dp[n],即 dp[6] = 9,表示将正整数 6 拆分后可以获得的最大乘积为 9。

class Solution {
public:int integerBreak(int n) {vector<int> dp(n+1);dp[1] = 0;dp[2] = 1;for(int i = 3; i <= n; i++){int maxm = 1;//i/2是一个改善措施,因为当j>i/2后所有的情况之前都已经产生过了for(int j = 1; j <= i/2; j++){int k = i-j;int temp = max(max(j*k,dp[j]*k),max(dp[k]*j,dp[j]*dp[k]));if(maxm < temp) maxm = temp;}dp[i] = maxm;}return dp[n];}
};

方法改良

在递推公式的计算部分,我们可以将递推公式简化为 dp[i] = max(j * k, j * dp[k]),并且不再计算 dp[j] * dp[k] 部分。

改良的原因:

  • 在原始的递推公式中,我们考虑了 j 和 k 是否继续拆分,计算了 dp[j] * dp[k] 部分,但实际上,这部分是在之前的状态中已经计算过的,而且不会再参与当前状态的计算。
  • 因此,我们可以直接在递推公式中计算 j * dp[k] 部分,而不再重复计算之前已经得到的 dp[j]。

改良后的代码如下:

cppCopy codeclass Solution {
public:int integerBreak(int n) {vector<int> dp(n + 1);dp[2] = 1;for (int i = 3; i <= n; i++) {int maxm = 1;for (int j = 1; j <= i / 2; j++) {int k = i - j;int temp = max(j * k, j * dp[k]);if (maxm < temp) maxm = temp;}dp[i] = maxm;}return dp[n];}
};

http://www.ppmy.cn/news/998251.html

相关文章

测试|LoadRunner安装及介绍

测试|LoadRunner安装及介绍 文章目录 测试|LoadRunner安装及介绍1.什么是LoadRunner2.LoadRunner特点3.LoadRunner基本概念4.LoadRunner三大组件之间关系LoadRunner安装1.安装包2.安装loadrunner 1.什么是LoadRunner LoadRunner是用来模拟用户负载完成性能测试的工具。 它适用…

01-Hadoop集群部署(普通用户)

Hadoop集群部署&#xff08;普通用户&#xff09; 环境准备 1&#xff09;准备3台客户机&#xff08;关闭防火墙、静态IP、主机名称&#xff09; 如果这一步已经配置过了&#xff0c;可以忽略 # 1 关闭防火墙 systemctl stop firewalld.service # 关闭当前防火墙 systemctl…

Vue中常用到的标签和指令

一、标签 在 Vue 中&#xff0c;并没有特定的标签是属于 Vue 的&#xff0c;因为 Vue 是一个用于构建用户界面的框架&#xff0c;可以与 HTML 标签一起使用。Vue 中可以使用的标签和元素基本上与 HTML 标准一致。 以下是一些常见的HTML标签&#xff0c;也可以在 Vue 中使用&a…

C#设计模式之---抽象工厂模式

抽象工厂模式&#xff08;Abstract Factory&#xff09; 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。工厂方…

vue3搭建(vite+create-vue)

目录 前提条件 输入命令 对于Add an End-to-End Testing Solution nightwatch和Cypress 和 Playwright 运行 前提条件 熟悉命令行已安装 16.0 或更高版本的 Node.js &#xff08;node -v查看版本&#xff09; 输入命令 npm init vuelatest 这一指令将会安装并执行 create-…

Redis - 数据过期策略

Redis提供了两种数据过期策略 惰性删除 和 定期删除 惰性删除 当某个key过期时&#xff0c;不马上删除&#xff0c;而是在调用时&#xff0c;再判断它是否过期&#xff0c;如果过期再删除它 优点 &#xff1a; 对CPU友好&#xff0c;对于很多用不到的key&#xff0c;不用浪费…

KL15 是什么?ACC,crank,on等

KL含义 KL is the abbreviation for klemme which is the German term for connector / connection.KL是“ klemme”的缩写&#xff0c;这是德语中连接器或连接的术语。 KL30 &#xff0c;通常表示电瓶的正极。positive KL31&#xff0c;通常表示电瓶的负极。negative KL15, 通…

TypeC拓展设计方案|TypeC转HDMI设计方案|CS5261/CS5265芯片设计参数对比

集睿智远CS5261/CS5265都可以用于设计TypeC转HDMI方案&#xff0c;低成本TypeC扩展坞设计方案&#xff0c;而两者也有些差异&#xff1a;1.CS5261支持DP1.4输入&#xff0c;一个HDMI1.4输出&#xff0c;即HDMI输出为4K30HZ ;CS5265DP1.4到HDMI2.0转换芯片&#xff0c;即HDMI输出…