DP进阶之路——整数拆分
2023-12-28 20:38:23
    		给定一个正整数?
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。
这种题目,我们第一眼肯定都是直接原地暴力破解,直接利用回溯去试一下?
?
class Solution {
    int max;
    int sum = 1;
    public int integerBreak(int n) {
        if(n == 2)  return 1;
        if(n == 3)  return 2;
        max = Integer.MIN_VALUE;
        dfs(n);
       
        return max;
    }
    void dfs(int n){
        if(n<0) return;
        if(n == 0){
            max=Math.max(max,sum);
            return;
        }
        for(int i =1;i<= n && n>0;i++){
            sum = sum*i;
            dfs(n-i);
            sum = sum/i;
        }
    }
}
结果很遗憾,经典时间超限。所以我们可以来进行优化一下。
可以通过记录我们已经运行过了乘积,免去多余的运行(可以说是剪枝)?
?
class Solution {
    public int integerBreak(int n) {
        if (n == 2) return 1;    
        if (n == 3) return 2;    //这里是两种的特殊情况
        return dfs(n, new int[n + 1]);
    }
    private int dfs(int n, int[] memo) {    //这里的memo数组就是用来记录运行过的
        if (n == 2) return 2;
        if (memo[n] > 0) return memo[n];    //如果大于0,就是已经被记录了,直接返回就行
        
        int max = 0;
        for (int i = 1; i < n; i++) {
            max = Math.max(max, i * Math.max(n - i, dfs(n - i, memo)));
        }
        memo[n] = max;
        return max;
    }
}一运行,我们就发现我们过了。然后,我们还可以通过递推优化,就是动态规划。
我们先要确定:dp[i] 是什么,其实是n == i时候的拆分出来的整数的最大乘积。
提出一个问题,这个怎么求出来呢?
?
?
我们其实可以有两种方式获得dp[i]
第一种:i*(n-i)? ? ? ? 这是两个数直接求
第二种:i*(dp[n-i])? ? ? ? 这里是和多个数求
class Solution {
    public int integerBreak(int n) {
        int[] dp = new int[n+1];
        dp[0] = dp[1] = 0;
        for(int i =2;i<=n;i++){
            int temp = 0;
            for(int j = 1;j<= i;j++){
                temp = Math.max(Math.max(j*(i-j),j*dp[i-j]),temp);
    //这里是比较两种求值的所有情况,最后获得最大值
            }
            dp[i] = temp;
        }
        return dp[n];
    }
}
    			文章来源:https://blog.csdn.net/qq_62074445/article/details/135276924
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!