【算法】最大连续乘积子串
2015-06-09 09:41
316 查看
from https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/05.01.md
给一个浮点数序列,取最大乘积连续子串的值,例如 -2.5,4,0,3,0.5,8,-1,则取出的最大乘积连续子串为3,0.5,8。也就是说,上述数组中,3 0.5 8这3个数的乘积30.58=12是最大的,而且是连续的。
此最大乘积连续子串与最大乘积子序列不同,请勿混淆,前者子串要求连续,后者子序列不要求连续。也就是说,最长公共子串(Longest CommonSubstring)和最长公共子序列(LongestCommon Subsequence,LCS)是:
子串(Substring)是串的一个连续的部分,
子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;
更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必。比如字符串“ acdfg ”同“ akdfc ”的最长公共子串为“ df ”,而它们的最长公共子序列LCS是“ adf ”,LCS可以使用动态规划法解决。
考虑到乘积子序列中有正有负也还可能有0,我们可以把问题简化成这样:数组中找一个子序列,使得它的乘积最大;同时找一个子序列,使得它的乘积最小(负数的情况)。因为虽然我们只要一个最大积,但由于负数的存在,我们同时找这两个乘积做起来反而方便。也就是说,不但记录最大乘积,也要记录最小乘积。
假设数组为a[],直接利用动态规划来求解,考虑到可能存在负数的情况,我们用maxend来表示以a[i]结尾的最大连续子串的乘积值,用minend表示以a[i]结尾的最小的子串的乘积值,那么状态转移方程为:
初始状态为maxend = minend = a[0]。
参考代码如下:
题目描述
给一个浮点数序列,取最大乘积连续子串的值,例如 -2.5,4,0,3,0.5,8,-1,则取出的最大乘积连续子串为3,0.5,8。也就是说,上述数组中,3 0.5 8这3个数的乘积30.58=12是最大的,而且是连续的。
分析与解法
此最大乘积连续子串与最大乘积子序列不同,请勿混淆,前者子串要求连续,后者子序列不要求连续。也就是说,最长公共子串(Longest CommonSubstring)和最长公共子序列(LongestCommon Subsequence,LCS)是:子串(Substring)是串的一个连续的部分,
子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;
更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必。比如字符串“ acdfg ”同“ akdfc ”的最长公共子串为“ df ”,而它们的最长公共子序列LCS是“ adf ”,LCS可以使用动态规划法解决。
考虑到乘积子序列中有正有负也还可能有0,我们可以把问题简化成这样:数组中找一个子序列,使得它的乘积最大;同时找一个子序列,使得它的乘积最小(负数的情况)。因为虽然我们只要一个最大积,但由于负数的存在,我们同时找这两个乘积做起来反而方便。也就是说,不但记录最大乘积,也要记录最小乘积。
假设数组为a[],直接利用动态规划来求解,考虑到可能存在负数的情况,我们用maxend来表示以a[i]结尾的最大连续子串的乘积值,用minend表示以a[i]结尾的最小的子串的乘积值,那么状态转移方程为:
maxend = max(max(maxend * a[i], minend * a[i]), a[i]); minend = min(min(maxend * a[i], minend * a[i]), a[i]);
初始状态为maxend = minend = a[0]。
参考代码如下:
double MaxProductSubstring(double *a, int length) { double maxEnd = a[0]; double minEnd = a[0]; double maxResult = a[0]; for (int i = 1; i < length; ++i) { double end1 = maxEnd * a[i], end2 = minEnd * a[i]; maxEnd = max(max(end1, end2), a[i]); minEnd = min(min(end1, end2), a[i]); maxResult = max(maxResult, maxEnd); } return maxResult; }
相关文章推荐
- ES6新特性概览
- Filter和FilterChain具体的使用说明
- MessageBox in iOS
- 我的Android系统学习笔记——HAL
- Course Schedule
- 【EPI-6.6】最长连续递增子序列-启发式搜索
- CentOS7 上源码安装KVM(qemu--kvm)
- 相关分析和回归分析
- OpenSLL之建立私有CA
- Thinking in Java 第四章、第五章
- Path Sum II
- 数据表字段属性查询
- centos下 iftop安装
- 页面向下滚动ajax获取数据,兼容手机
- 隐马尔科夫学习五(四)
- MBProgressHUD等待指示器
- Dialog显示在Activity不同的位置
- lambda表达式
- Linux-VMware三种网络模式
- JS回到顶部按钮