动态规划解决最大乘积系列问题(碾压暴力枚举)java

简介: 动态规划( Dynamic Programming )算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

1.例题

题目描述

  1. 思路分析

基本思想

具体步骤

3.代码实现

4.DP小结

注意

1.例题
题目描述
输入n个元素组成的子串S,你需要找出一个乘积最大的连续的子串。

如果这个最大的乘积不是正数,应输出0(表示无解)。

输入

第一行是一个整数n(1<=n<=18)。

第二行是n个整数。其中每个整数的范围是[-10,10]。

输出

输出一行包含一个整数,输出最大乘积。

测试数据

见代码。

  1. 思路分析

基本思想
题目类似背包问题,,其基本思想可以使用动态规划:记住已经解决过的子问题的解。求解,即在遍历数据的时候,将遍历过程中求得的最大乘积记录下来,再继续遍历,通过每次遍历,动态的更新最大乘积,最终求得的就是最终解。

对于此类题目可以定义两个变量max和min,用来记录过程中的最大值和最小值。cur表示计算过程中的当前要计算的数据。每次计算过程中,max取Max.(cur,curmax,curmin)中的最大值,min取Min.(cur,curmax,curmin)中的最小值。

具体步骤
1) 初始化cur,max,min数据,默认都为第一个数。

2)循环计算数组元素。

3)每次循环max,min都乘以当前元素cur。并用临时变量保存。

4)计算新的max和min并重新赋值。

5)计算过程中新的最大值ans=Max(max,ans)。

6)遍历完后打印ans。

3.代码实现

import java.util.Scanner;

public class Main {

static long[] nums;// 用来存放数据

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int m = scanner.nextInt();
    /**
     * long cur 当前数据 long max 最大数 long min 最小数 long ans 最终结果
     */
    long cur, max, min, ans = 0;
    // 录入数据
    for (int i = 0; i < m; i++)
        nums[i] = scanner.nextLong();
    // 初始化数据,默认都为第一个数
    cur = nums[0];
    max = nums[0];
    min = nums[0];
    for (int i = 1; i < m; i++) {
        cur = nums[i];// 当前处理的数
        long tempmax = max * cur;// 当前数cur乘以最大数max,定义一个临时变量tempmax储存
        long tempmin = min * cur;// 当前数cur乘以最小数min,定义一个临时变量tempmin储存
        // 新的max在上面三个数中产生
        /* 因为max在下一步求min时还要用到,因此这里定义一个临时变量储存newmax */
        long newmax = Math.max(cur, Math.max(tempmax, tempmin));
        min = Math.min(cur, Math.min(tempmax, tempmin));
        max = newmax;// max使用完后,将新的newmax赋值给max
        ans = Math.max(ans, max);// 数据处理过程中的答案在ans和max中产生
    }
    System.out.println(ans);
}

}

4.DP小结
注意
动态规划( Dynamic Programming )算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法
动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)
动态规划可以通过填表的方式来逐步推进,得到最优解.

相关文章
|
6月前
|
Java
0-1背包问题(Java详解)(动态规划)至少与恰好
0-1背包问题(Java详解)(动态规划)至少与恰好
57 1
【Java每日一题,动态规划,零钱兑换模板题】硬币组合数量
【Java每日一题,动态规划,零钱兑换模板题】硬币组合数量
|
3月前
|
算法 Java 索引
LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解
LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解
36 0
|
5月前
|
算法 Java 决策智能
Java数据结构与算法:动态规划之背包问题
Java数据结构与算法:动态规划之背包问题
【Java每日一题,动态规划】数字金字塔
【Java每日一题,动态规划】数字金字塔
|
6月前
|
C++ Java Go
Java每日一练(20230425) 乘积最大子数组、插入区间、删除有序数组中的重复项II
Java每日一练(20230425) 乘积最大子数组、插入区间、删除有序数组中的重复项II
53 0
Java每日一练(20230425) 乘积最大子数组、插入区间、删除有序数组中的重复项II
|
6月前
|
Java
乘积尾零(Java详解)
乘积尾零(Java详解)
82 0
|
6月前
|
算法 Java
给定一个字符串数组,如何找到其中最长的回文子串? 要求:编写一个Java函数,输入一个字符串数组,输出其中最长的回文子串。要求时间复杂度为O(n^2)。可以考虑使用动态规划或中心扩展的方法来优化算法。
给定一个字符串数组,如何找到其中最长的回文子串? 要求:编写一个Java函数,输入一个字符串数组,输出其中最长的回文子串。要求时间复杂度为O(n^2)。可以考虑使用动态规划或中心扩展的方法来优化算法。
85 1
【Java每日一题,动态规划,Map实现】最长定差子序列
【Java每日一题,动态规划,Map实现】最长定差子序列
【Java每日一题,动态规划】最长定差子序列
【Java每日一题,动态规划】最长定差子序列