洛谷P1182 数列分段【二分】【贪心】

题目https://www.luogu.org/problemnew/show/P1182

题意:

有n个数,要分成连续的m段。将每段中的数相加,问之和的最大值的最小值是多少。

思路:

和P1316丢瓶盖很像,就是反一下而已。

同样是二分答案,然后检查一下当前的答案可不可行,如果可行由于需要得到最小值,所以缩小上界。

要注意的点是,st的初始化应该是num中的最大值而不是随意给一个0

这会影响到分段的计数。

如果当前值是比某一个num要小的话,cnt还是+1了。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<map>
 4 #include<set>
 5 #include<iostream>
 6 #include<cstring>
 7 #include<algorithm>
 8 #include<vector>
 9 #include<cmath> 
10 #include<queue>
11 
12 #define inf 0x7fffffff
13 using namespace std;
14 typedef long long LL;
15 typedef pair<int, int> pr;
16 
17 int n, m;
18 const int maxn = 1e5 + 5;
19 int num[maxn];
20 
21 bool check(int x)
22 {
23     int cnt = 0;
24     int tot = 0;
25     for(int i = 1; i <= n; i++){
26         if(tot + num[i] <= x){
27             tot += num[i];
28         }
29         else{
30             tot = num[i];
31             cnt++;
32         }
33     }
34     if(tot <= x)cnt++;
35     if(cnt <= m)return true;
36     else return false;
37 }
38 
39 int main()
40 {
41     scanf("%d%d", &n, &m);
42     int st = 0, ed = 0;
43     for(int i = 1; i <= n; i++){
44         scanf("%d", &num[i]);
45         ed += num[i];
46         st = max(st, num[i]);
47     }
48     int ans;
49     while(st <= ed){
50         int mid = (st + ed) / 2;
51         if(check(mid)){
52             ed = mid - 1;
53             ans = mid;
54         }
55         else{
56             st = mid + 1;
57         }
58     }
59     printf("%d\n", st);
60     return 0;
61 }

 

---恢复内容结束---

posted @ 2019-02-15 22:31  wyboooo  阅读(355)  评论(0编辑  收藏  举报