zoukankan      html  css  js  c++  java
  • 最大值最下化

    目标:
        学会用猜数字(二分)的方法,换个角度来解决问题(参考刘汝佳的<<算法入门经典>>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 }
  • 相关阅读:
    TFS的安装
    反射发出动态类型介绍(上)
    搭建基于SSI(struts2,spring,ibatis)的javaEE开发环境
    国内各大互联网公司相关技术站点2.0版
    第三部分 静态链接(一)
    谁删除了某个表
    迷你MVVM框架 avalonjs 0.85发布
    POJ 2367 Genealogical tree
    修改进程占用内存SetProcessWorkingSetSize函数(多篇相关文章值得学习)
    使用TWebBrowser时存在内存泄漏问题的解决方案(使用SetProcessWorkingSetSize函数,或者修改OleCtrls.pas源码解决问题)
  • 原文地址:https://www.cnblogs.com/dongsheng/p/3024331.html
Copyright © 2011-2022 走看看