• 最大值最下化


    目标:
        学会用猜数字(二分)的方法,换个角度来解决问题(参考刘汝佳的<<算法入门经典>>P151)
    问题描述:
             把一个包含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,不是最小。

    问题分析:
            能否使m个连续子序列所有的s(i)均不超过x,则该命题成立的最小的x即为答案。该命题不难判断,
        只需贪心,每次尽量从左向右尽量多划分元素即可。
        我们把该问题转化为递归分治问题,类似于二分查找。首先取Sum和元素最大值的中值x,
        如果命题为假,那么答案比x大;
        如果命题为真,则答案小于等于x。问题得解,复杂度为O(n*logSum)

    实现代码:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 int A[1000];
     6 int n, m;
     7 
     8 bool judge(int sum)  // 判断分成最大和为sum 的 m 个子序列是否可以
     9 {
    10     int cnt = 0;//记录划分线的个数
    11     int tmp = 0;
    12     //每次都尽量往右划分,划分完后,所用的划分线不大于m-1个即可
    13     for(int i = 0; i < n; ++i)
    14     {
    15         if(tmp+A[i] <= sum)
    16             tmp += A[i];
    17         else
    18         {
    19             tmp = A[i];
    20             ++cnt;
    21         }
    22         if(cnt > m-1)
    23             return false;
    24     }
    25     return true;
    26 }
    27 int binary_solve(int x, int y)
    28 {
    29     while(x < y)
    30     {
    31         int mid = x + ((y-x)>>1);
    32         if(judge(mid))
    33             y = mid;
    34         else
    35             x = mid + 1;
    36     }
    37     return x;
    38 }
    39 
    40 int main()
    41 {
    42     int min, max;// min 和 max 分别是枚举的下限和上限,注意初始值的设计
    43     while(cin >> n >> m)
    44     {
    45         min = -1;
    46         max = 0;
    47         for(int i = 0; i < n; ++i)
    48         {
    49             cin >> A[i];
    50             if(min < A[i])
    51                 min = A[i];
    52             max += A[i];
    53         }
    54         cout << binary_solve(min, max) << endl;
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    巨蟒python全栈开发-第11阶段 ansible_project4
    正则面试题
    正确的邮件发送格式?
    巨蟒python全栈开发-第11阶段 ansible_project3
    巨蟒python全栈开发-第11阶段 ansible_project2
    项目资源地址
    网络基础练习题
    巨蟒python全栈开发-第11阶段 ansible_project1
    数据库之单表查询
    数据的增删改
  • 原文地址:https://www.cnblogs.com/dongsheng/p/3024331.html
Copyright © 2020-2023  润新知