22. 序列划分
来源:互联网 发布:poser人体造型软件 编辑:程序博客网 时间:2024/06/13 02:26
给定一个由非负整数组成的序列及正整数 m,将原始的序列划分成 m 个连续的子序列。针对每个划分,计算 m 个子序列中最大和,针对所有可能的划分,找出最小的最大子序列和。如,给定序列为 [7,2,5,10,8] 及划分个数 m = 2,可得到 4 种划分:
- [7] 和 [2,5,10,8],最大子序列和为 25
- [7,2] 和 [5,10,8],最大子序列和为 23
- [7,2,5] 和 [10,8],最大子序列和为 18
- [7,2,5,10] 和 [8],最大子序列和为 24
因此,可以得出最小的最大序列和为 18。
输入
第一行输入两个整数 n m,其中 n 代表序列的长度,m 代表划分个数,1 ≤ n ≤ 1000,1 ≤ m ≤ min(50, n)
接下来的一行为序列中的 n 个非负整数(取值范围 0~10000),用空格分隔。
输出
最小的最大子序列和。
- 5 2↵
- 7 2 5 10 8↵
- 18↵
//问题分析://能否使m个连续子序列所有的s(i)均不超过x,则该命题成立的最小的x即为答案。该命题不难判断,只需贪心,每次尽量从左//向右尽量多划分元素即可。//我们把该问题转化为递归分治问题,类似于二分查找。首先取Sum和元素最大值的中值x,如果命题为假,那么答案比x大;//如果命题为真,则答案小于等于x。问题得解,复杂度为O(n*logSum)#include<stdio.h>int num[1005], n, m,Max=0,Left=0,Right=0;/* 判断划分所子序列其和是否都不大于x 是-1,否-0*/int Judge(int SumMin) {//每次往右划分,划分完后,所用的划分线不大于m-1个即可 int count = 0, LeftSum = 0;//count已划分子序列个数(其实count的值为划分斜杠个数),LeftSum即将划分的序列从右开始累和for (int i = 0; i<n; i++){if (num[i]>SumMin) return 0;//如果序列中有元素的值大于SumMin,则无论怎么划分都不成立if (LeftSum + num[i]>SumMin) {count++; LeftSum = num[i];if (count>m - 1) return 0;//已划分的子序列个数超过m}elseLeftSum += num[i]; }return 1;}int BinarySelect(){while (Left<Right){int mod = Left + (Right - Left) / 2;if (Judge(mod)) Right = mod;else Left = mod + 1;}return Left;}int main(){scanf("%d %d", &n, &m);for (int i = 0; i < n; i++){scanf("%d", &num[i]);if (num[i] > Left)Left = num[i];Right += num[i];}printf("%d\n",BinarySelect());return 0;}
阅读全文
0 0
- 22. 序列划分
- BIT 程序设计与实践 22.序列划分
- 序列的划分
- 序列的划分(2)
- 快速排序的划分子序列思想:
- 序列划分-使其最大值最小化
- Java序列划分问题算法实现
- UVA 11552 Fewest Flops(序列划分dp)
- UVA 11552 Fewest Flops (序列划分DP,4级)
- 数据结构——最大值最小化 (划分子序列)
- poj 1505 dp/二分+贪心 序列划分模型
- web页面抽取结构五元组的序列划分生成
- UVA-11552-Fewest Flops(DP 序列划分)
- 动态规划 之 回文序列的最小划分
- 将数组划分最少数目的排序子序列
- 划分
- 划分
- 以指定字符重新划分段落并插入时间序列数(VBA)
- HEVC函数入门(2)——帧内编码一个CU
- 【c++】简单异常处理笔记
- 读《李善友:你与高手的距离,并非只差了一万小时练习》有感
- 关于linux系统环境变量的一点理解
- 51nod 1577 异或凑数
- 22. 序列划分
- Web Worker 调用Ajax
- bzoj3790 神奇项链
- 线程死锁调研
- 第一次面试
- [bidata-102] 一个最简单的spring boot[1.3.8/1.5.4]的web应用
- Linux下的系统编程总结
- 23. 单词接龙
- Android 实现左滑出现删除选项