九度1502 最大值最小化问题

问题描述:

把一个包含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,不是最小。

[2018.3.18补充]

就是不断去尝试那个最大值m, 如果以m为最大值看看是不是能划分m个子序列,如果可以的话,那么就可以往小了再试试,如果根本不能划分m个子序列,会剩下一些数,那么最大值就要变大一点

参考博客:http://blog.csdn.net/nanjunxiao/article/details/8145971

 

这个答案就是介于这六个数最大值和总和之间的一个,然后就二分查找,判断是否mid可以,

判断mid就是一个循环看看是否最多插m - 1(少没事,多就不行)个空,是每一段和少于等于mid。

题目1502:最大值最小化http://ac.jobdu.com/problem.php?pid=1502

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:540

解决:201

题目描述:

在印刷术发明之前,复制一本书是一个很困难的工作,工作量很大,而且需要大家的积极配合来抄写一本书,团队合作能力很重要。
当时都是通过招募抄写员来进行书本的录入和复制工作的, 假设现在要抄写m本书,编号为1,2,3...m, 每本书有1<=x<=100000页, 把这些书分配给k个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的。每个抄写员的速度是相同的,你的任务就是找到一个最佳的分配方案,使得所有书被抄完所用的时间最少。

 

输入:

输入可能包含多个测试样例。
第一行仅包含正整数 n,表示测试案例的个数。
对于每个测试案例,每个案例由两行组成,在第一行中,有两个整数m和 k, 1<=k<=m<=500。 在第二行中,有m个整数用空格分隔。 所有这些值都为正且小于100000。

 

输出:

对应每个测试案例,
输出一行数字,代表最佳的分配方案全部抄写完毕所需要的时间。

 

样例输入:
2
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100
样例输出:
1700
200
来源:
网易有道2013年校园招聘面试一面试题
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 const int MAX = 500 + 10;
 7 int m,k;
 8 int a[MAX];
 9 bool is_ok(int maxn)
10 {
11     bool ok = true;
12     int s = 0,cnt = 0;
13     for(int i = 1; i <= m; i++)
14     {
15         if(a[i] > maxn)
16         {
17             ok = false;
18             break;
19         }
20         if(s + a[i] > maxn)
21         {
22             cnt++;
23             s = a[i];
24             if(cnt > k - 1)
25             {
26                 ok = false;
27                 break;
28             }
29         }
30         else
31         {
32             s += a[i];
33         }
34     }
35     return ok;
36 }
37 int solve(int x, int y)
38 {
39     while(x <= y)
40     {
41         int mid = (x + y) / 2;
42         if( is_ok(mid) )
43             y = mid - 1;
44         else
45             x = mid + 1;
46     }
47     return x;
48 }
49 int main()
50 {
51     int t;
52     scanf("%d", &t);
53     while(t--)
54     {
55         int maxn = 0,sum = 0;
56         scanf("%d%d", &m, &k);
57         for(int i = 1; i <= m; i++)
58         {
59             scanf("%d", &a[i]);
60             if(maxn < a[i])
61                 maxn = a[i];
62             sum += a[i];
63         }
64         printf("%d\n", solve(maxn, sum));
65     }
66     return 0;
67 }
View Code

 

posted @ 2016-02-02 15:29  zhaop  阅读(286)  评论(0编辑  收藏  举报