zoukankan      html  css  js  c++  java
  • 【模板】【P1182】数列分段II——二分答案

    题意:给定一列数,分成m段,使每段和的最大值最小。

      考虑二分最小段和size,答案显然满足单调性。可以在每次check中累加数列元素判断当前组的总和是否在size以内。由于序列元素均为非负整数,前缀和数组的值满足非严格单调递增,那么可以在前缀和上再套一个二分来优化暴力累加的过程。

      我不知道优化以后的复杂度怎么分析,反正它跑的快多了

    代码:

    1. #include <iostream>  
    2. #include <cstdio>  
    3. #define maxn 100010   
    4. using namespace std;  
    5. int a[maxn], n, m;  
    6. long long s[maxn];  
    7. bool div(int sum) {  
    8.     int cnt = 0;  
    9.     for (int i = 1; i <= n; ) {  
    10.         if (a[i] > sum) return false;  
    11.         int l = i, r = n;  
    12.         while (l < r) {  
    13.             int mid = (l + r + 1) >> 1;  
    14.             s[mid] - s[i - 1] <= sum ? l = mid : r = mid - 1;  
    15.         }  
    16.         ++cnt, i = l + 1;  
    17.     }  
    18.     return cnt <= m;  
    19. }  
    20. int main() {  
    21. //  freopen("testdata-10.in", "r", stdin);  
    22.     ios::sync_with_stdio(0);  
    23.     cin >> n >> m;  
    24.     int l = 0, r = 0;  
    25.     for (int i = 1; i <= n; ++i)  
    26.         cin >> a[i], s[i] = a[i] + s[i - 1], l = max(l, a[i]);  
    27.     r = s[n];  
    28.     while (l < r) {  
    29.         long long mid = (l + r) >> 1;  
    30.         if (div(mid))  
    31.             r = mid;  
    32.         else l = mid + 1;  
    33.     }  
    34.     cout << l;  
    35.     return 0;  
    36. }  
  • 相关阅读:
    ZendStudio 解决svn导出项目乱码问题
    Linux常用命令
    php类与对象
    Apache shutdown unexpectedly启动错误解决方法
    php构造函数和析构函数
    MySQL基本概念
    Javascript中常用事件的命名
    网页布局
    页面的自动滚动效果
    表单验证和事件(2)
  • 原文地址:https://www.cnblogs.com/TY02/p/11366562.html
Copyright © 2011-2022 走看看