zoukankan      html  css  js  c++  java
  • 今日头条 2018 AI Camp 5 月 26 日在线笔试编程题第二道——最小分割分数

    题目:

    给 n 个正整数 a_1,…,a_n, 将 n 个数顺序排成一列后分割成 m 段,每一段的分数被记为这段内所有数的和,该次分割的分数被记为 m 段分数的最大值。问所有分割方案中分割分数的最小值是多少?

      • 输入描述: 
        第一行依次给出正整数 n, m。 
        第二行依次给出n 个正整数 a1,...,ana1,...,an。

      • 示例:

        输入 
        5 3 
        1 4 2 3 5 
        输出 
        5

      • 说明 
        分割成 1 4 | 2 3 | 5 的时候三段的分数都为 5,得到分割分数的最小值。

      • 备注: 
        对于所有的数据,有 m <= n <= 100000,0 <= aiai <= 2^39。

      • 思路

        1. 将 n 个数划分为 n 段,分割分数即为 n 个正整数的最大值;
        2. 将 n 个数划分为 1 段,分割分数即为 n 个正整数的和;
        3. 若分为 m 段,则分割分数一定介于最大值与和之间。因此采用二分查找,每次取一个值对序列进行划分,若能划分出 
          m 段,使得每段的和都小于这个数值,则满足划分,反之不满足,直至找到一个最小的满足划分的值为止。
      • 代码实现如下:

    #include <iostream>
    using namespace std;
    
    int Judge(int data[], int sum, int m, int n);
    int Binary_Search(int data[], int left, int right, int m, int n);
    
    
    int main()
    {
        int n = 0, m = 0;
        cin >> n >> m;
    
        int data[n];
        int max_num = 0;
        int sum = 0;
    
        int i = 0;
    
        for(i = 0; i < n ; i++)
        {
            cin >> data[i];
            if (data[i] > max_num)
            {
                max_num = data[i];
            }
            sum += data[i];
        }
    
        cout << Binary_Search(data, max_num, sum, m, n);
    
        return 0;
    }
    
    int Binary_Search(int data[], int left, int right, int m, int n)
    {
        int mid = 0;
    
        while (left < right)
        {
            mid = left + (right - left) / 2;
            if (Judge(data, mid, m, n)) //满足划分,继续向左寻找
            {
                right = mid;//不减是因为无法确保减一之后的数是否满足划分
            }
            else    //不满足划分,继续向右寻找
            {
                left = mid + 1;
            }
        }
    
        return left;
    }
    
    int Judge(int data[], int mid, int m, int n)
    {
        int cnt = 0;
        int sum = 0;
    
        for (int i = 0; i < n; i++)
        {
            if (sum + data[i] > mid) //累加和大于 mid,进行一次划分
            {
                sum = data[i];
                cnt++;
                if (cnt > m - 1)    //划分次数大于 m-1,不满足划分
                {
                    return 0;
                }
            }
            else
            {
                sum += data[i];
            }
        }
    
        return 1;
    }

    个人见解,如有错误,欢迎指正与交流!

    获取更多精彩,请关注「seniusen」!

     
  • 相关阅读:
    OpenWrt配置绿联的usb转Ethernet网口驱动
    SQL_wm_concat函数实验:实现字段合并
    BingMap频繁Add Pushpin和Delete Pushpin会导致内存泄露
    比較C++和Java 二
    【JAVASE】Java同一时候抛出多个异常
    uva 1463
    Android 撕衣服(刮刮乐游戏)
    轻松掌握一致性哈希算法
    Oracle之sql语句优化
    Eclipse导出Library
  • 原文地址:https://www.cnblogs.com/seniusen/p/9143685.html
Copyright © 2011-2022 走看看