博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj1505
阅读量:6702 次
发布时间:2019-06-25

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

题意:给出一个数列有n个数,要求用分割分把这个数列分成m段,不能改变原数列的顺序。每段至少一个数。求使得加和最大的那段的加和最小的划分方案。如果有多组解的话先要保证第一段和尽量小,若仍有多组解,要先保证第二段和尽量小,以此类推。

分析:二分+贪心。二分查找这个加和最大的段的加和最小值。在查找过程中,每次枚举这个加和,对数列从左到右看一遍,看在每段加和不超过这个枚举值的前提下最少可以将这个数列分成几段。如果分段数小于等于m则这个枚举值偏大或者刚刚好,如果大于m则说明枚举值偏小。

找到了这个值之后,我们开始求最优方案,我的做法是先保证最右面那段加和尽量大,其次右数第二段加和尽量大,以此类推。虽然与题中的左面最小的方案不同,但是最终结果是一样的,因为符合题目要求的那组解一定是左面最小,最终一定会导致右面最大。对于这种右面最大的方式,只需要从右到左将数列走一遍即可。注意处理保证右边最大之后划分的段数不足m的情况,要做相应调整以满足每段至少一个数的要求。即将依次左面没有分隔符的空位画上分隔符。

#include 
#include
#include
#include
#include
#include
using namespace std;#define MAX_BOOK_NUM 505int book_num, scriber_num;long long book[MAX_BOOK_NUM];bool cut_before[MAX_BOOK_NUM];void input(){ scanf("%d%d", &book_num, &scriber_num); for (int i = 0; i < book_num; i++) scanf("%lld", &book[i]);}bool ok(long long a){ long long temp = 0; int cnt = 1; for (int i = 0; i < book_num; i++) { if (temp + book[i] <= a) { temp += book[i]; continue; } temp = book[i]; cnt++; if (cnt > scriber_num) return false; } return cnt <= scriber_num;}long long binary_search(){ long long l = *max_element(book, book + book_num); long long r = accumulate(book, book + book_num, 0); while (l < r) { long long mid = (l + r) / 2; if (ok(mid)) r = mid; else l = mid + 1; } return l;}void work(){ long long each = binary_search(); memset(cut_before, 0, sizeof(cut_before)); long long temp = 0; int cnt = 0; for (int i = book_num - 1; i >= 0; i--) { if (temp + book[i] <= each) { temp += book[i]; continue; } cut_before[i + 1] = true; temp = book[i]; cnt++; } int i = 0; while (cnt < scriber_num - 1) { i++; if (!cut_before[i]) { cut_before[i] = true; cnt++; } }}void output(){ printf("%lld", book[0]); for (int i = 1; i < book_num; i++) { if (cut_before[i]) printf(" /"); printf(" %lld", book[i]); } putchar('\n');}int main(){ int t; scanf("%d", &t); while (t--) { input(); work(); output(); } return 0;}
View Code

 

转载地址:http://ndgoo.baihongyu.com/

你可能感兴趣的文章
国家自科委管文科学部认定的国内30种重要期刊
查看>>
表单验证
查看>>
原生JS数组去重的几种方法
查看>>
POJ——字符串插入
查看>>
1088. [SCOI2005]扫雷Mine【网格DP】
查看>>
BZOJ1718:[USACO]Redundant Paths 分离的路径(双连通分量)
查看>>
Java Decompiler(Java反编译工具)
查看>>
win下php的memcached的安装与使用
查看>>
git 常用命令笔记
查看>>
php使用supervisor管理进程脚本
查看>>
5.19 - Stacks and Queues
查看>>
读取config文件中的键值
查看>>
Starling框架帮助手册中文版(PDF下载)
查看>>
(五)Maven中的聚合和继承
查看>>
(三)SpringBoot之配置文件详解:Properties和YAML
查看>>
实验一报告
查看>>
JsRender 前端渲染模板常用API学习
查看>>
MySQL数据库引擎介绍、区别、创建和性能测试的深入分析
查看>>
【分布式计算】MapReduce的替代者-Parameter Server
查看>>
CodeVS 1044 拦截导弹(DP)
查看>>