博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最大值最小化问题
阅读量:6644 次
发布时间:2019-06-25

本文共 1317 字,大约阅读时间需要 4 分钟。

问题描述:

把一个包含n个正整数的序列划分成m个连续的子序列。设第i个序列的各数之和为S(i),求所有S(i)的最大值最小是多少?

例如序列1 2 3 2 5 4划分为3个子序列的最优方案为 1 2 3 | 2 5 | 4,其中S(1),S(2),S(3)分别为6,7,4,那么最大值为7;

如果划分为 1 2 | 3 2 | 5 4,则最大值为9,不是最小。

 

问题分析:

能否使m个连续子序列所有的s(i)均不超过x,则该命题成立的最小的x即为答案。该命题不难判断,只需贪心,每次尽量从左

向右尽量多划分元素即可。

我们把该问题转化为递归分治问题,类似于二分查找。首先取Sum和元素最大值的中值x,如果命题为假,那么答案比x大;

如果命题为真,则答案小于等于x。问题得解,复杂度为O(n*logSum)

代码:

 

#include
#include
using namespace std;int divide = 3;int main(){ vector
a = { 9, 19, 15, 13, 13, 9, 14, 1, 1, 7 }; int max = INT_MIN; int sum = 0; for (int i = 0; i < a.size(); i++) { if (max < a[i]) { max = a[i]; } sum += a[i]; } int left = max; int right = sum; int min = INT_MAX; while (left < right) { int middle = (left + right) / 2; int m = 0; int n = 0; int i; for (i = 0; i < a.size(); i++) { m += a[i]; if (m<=middle) continue; m = a[i]; n++; } n++; if (n <= divide) { if (middle < min) min = middle; right = middle - 1; } else left = middle + 1; } cout << min << endl;}

 

转载于:https://www.cnblogs.com/chaiwentao/p/4483584.html

你可能感兴趣的文章
我的友情链接
查看>>
Java解析json串
查看>>
ubuntu12.04 NFS搭建指南
查看>>
Sublime Text 使用介绍、全套快捷键及插件推荐
查看>>
toolbar
查看>>
spring boot 项目,maven打jar包时,将本地jar一块打入包
查看>>
Windows Server 2012 虚拟化实战:存储(一)
查看>>
linux shell 计算时间差并显示按时分秒显示
查看>>
iptables防火墙
查看>>
最大子序列和问题的解——C++实现;
查看>>
Shell脚本语言
查看>>
.NET快速开发平台,开发效率倍增神器
查看>>
阿里云 Aliplayer高级功能介绍(六):进度条标记
查看>>
【Python学习笔记】数据结构—序列——list列表和tuple元组
查看>>
Oracle 11G r2 Rac修改IP
查看>>
企业为什么需要IT资产管理
查看>>
Linux安装Mongodb4.0及远程配置
查看>>
大文件分割 - split
查看>>
光照模型与面绘制算法---OpenGL光照和表面绘制函数
查看>>
系统文件的损坏导致Windows XP连续重启的解决方案
查看>>