leetcode 343. 整数拆分:动态规划(c++)

  • leetcode 343. 整数拆分
  • 分析
    1. 状态表示:

      · dp[i] 表示整数 i 拆分乘积的最大值。

    2. 转移方程:

      · 对于每个数字 i 都进行一遍循环,计算 (i - j) * j,(j <= i - 1),并求其与 dp[i],dp[i - j] * j 的最大值,即:dp[i] = max(dp[i],(i - j) * j,dp[i - j] * j)

      · 与 dp[i - j] * j 比较是因为 i - j 可能小于 i - j 拆分的乘积。

    3. 边界:

      · 输入的整数 n 大于等于 2,考虑到会拆分成类似 (i - 1) * 1 等类型,故dp[1] = 1

  • 实现
    class Solution {
    public:
        int integerBreak(int n) {
            int dp[n + 1];
            memset(dp, -1, sizeof(dp));
    
            dp[1] = 1;
    
            for(int i = 2; i <= n; ++i) {
                for(int j = 1; j <= i - 1; ++j) {
                    dp[i] = max(dp[i], dp[i - j] * j);
                    dp[i] = max(dp[i], (i - j) * j);
                }
            }
    
            return dp[n];
        }
    };
  • 小结
    1. 确定状态转移的方式:想求dp[i],应先求dp[i - j],(j <= i - 1)
    2. 确定状态转移方程:明确拆分时的可能乘积,本题有两个 (i - j) * j 和 j * dp[i - j]
    3. 确定边界

原文地址:https://www.cnblogs.com/joe-w/p/12323050.html

时间: 2024-11-05 19:41:55

leetcode 343. 整数拆分:动态规划(c++)的相关文章

LeetCode 343.整数拆分 - JavaScript

题目描述:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 题目分析 题目中"n 至少可以拆分为两个正整数的和",这个条件说明了 n 是大于 1 的整数. 对 7 来说,可以拆成 3+4,最大乘积是 12. 对 8 来说,可以拆成 3+3+2,最大乘积是 18. 解法 1: 动态规划 状态数组dp[i]表示:数字 i 拆分为至少两个正整数之和的最大乘积.为了方便计算,dp 的长度是 n + 1,值初始化为 1. 显然dp[2]等于

[LeetCode] 139. 单词拆分 ☆☆☆(动态规划 回溯)

139. 单词拆分 描述 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 说明: 拆分时可以重复使用字典中的单词.你可以假设字典中没有重复的单词.示例 1: 输入: s = "leetcode", wordDict = ["leet", "code"]输出: true解释: 返回 true 因为 "leetcode" 可以被拆分成 "

整数拆分问题的四种解法【转载】

http://blog.csdn.net/u011889952/article/details/44813593 整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 标签: 算法 / 母函数定理 / 五边形数定理 / acm / 动态规划 整数划分问题是算法中的一个经典命题之一 所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分. 如果{m1,

【转载转载转载!】整数拆分问题的四种解法--尼奥普兰

整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 标签: 算法 / 母函数定理 / 五边形数定理 / acm / 动态规划 整数划分问题是算法中的一个经典命题之一 所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分. 如果{m1,m2,m3,....,mi}中的最大值不超过m,即max{m1,m2,m3,....,mi} <= m,则称

整数拆分

将一个整数N拆分成n个连续自然数的和.例如: 15 = 1+2+3+4+5 15 = 4+5+6 15 = 7+8 实现一个函数,打印所有可能,并且统计有多少种方法? 分析过程如下. 对于一个数N, 2个自然数相加:m+(m+1)                                                                                                                  =2m+1 3个自然数相加:(m-1)+m

Pollard-Rho大整数拆分模板

随机拆分,简直机智. 关于过程可以看http://wenku.baidu.com/link?url=JPlP8watmyGVDdjgiLpcytC0lazh4Leg3s53WIx1_Pp_Y6DJTC8QkZZqmiDIxvgFePUzFJ1KF1G5xVVAoUZpxdw9GN-S46eVeiJ6Q-zXdei 看完后,觉得随机生成数然后和n计算gcd,可以将随机的次数根号一下.思想很叼. 对于里面说的birthday trick,在执行次数上我怎么看都只能减一半.只是把平均分布,变成了靠近0

poj 1221 UNIMODAL PALINDROMIC DECOMPOSITIONS 整数拆分

题意: 给一个数n,求有多少种和为n的单峰先增对称序列,比如当n=5时结果为3:(5), (1 3 1), (1 1 1 1 1). 分析: 转化为求类似整数拆分问题,f(i,j)的意义是把i进行拆分,最大数小于等于j的方法数. 代码: //poj 1221 //sep9 #include <iostream> using namespace std; const int maxN=300; __int64 a[maxN+10][maxN+10]; __int64 f(int m,int n)

poj 2229 完全背包变形(求解整数拆分问题)

整数拆分问题:给定一个正整数n,将n拆分为若干数字的和,问有多少种方法? 此题为整数拆分问题的子问题,拆分出的数字要求是2的幂次. 定义dp[i][k]表示枚举到第k个数字时数字i的拆分方案数. 则有状态转移方程: dp[i][k] = dp[i][k - 1] + dp[i - num[k]][k]; 熟悉完全背包的朋友可以看出,这个方程和完全背包的状态转移方程如出一辙,第二维可以省去,只要将i从小到大枚举即可. 1 #include <iostream> 2 #include <cs

poj 3014 Cake Pieces and Plates 整数拆分

题意: 将m拆成n个数,允许某个数为0,求拆分方案数. 分析: 裸的整数拆分,设h(m,n)表示将m拆成n个数,允许某数为0的方案数,递推方程见代码.很有意思的是,参考上一篇写poj1221的博文中,设f(m,n)表示将m进行任意份数不允许有0的整数拆分,且最大元素小于等于m的方案数,则h(m,n)==f(m,n)....求解此等式意义... 代码: //poj 3014 //sep9 #include <iostream> using namespace std; const int max