列表

详情


XM31. 最优分割

描述

依次给出n个正整数A1,A2,… ,An,将这n个数分割成m段,每一段内的所有数的和记为这一段的权重, m段权重的最大值记为本次分割的权重。问所有分割方案中分割权重的最小值是多少?

输入描述

第一行依次给出正整数n,m,单空格切分;(n <= 10000, m <= 10000, m <= n)
第二行依次给出n个正整数单空格切分A1,A2,… ,An (Ai <= 10000)

输出描述

分割权重的最小值

示例1

输入:

5 3
1 4 2 3 5

输出:

5

说明:

分割成 1 4 | 2 3 | 5 的时候,3段的权重都是5,得到分割权重的最小值。

原站题解

C 解法, 执行用时: 3ms, 内存消耗: 404KB, 提交时间: 2020-09-08

#include <stdio.h>
  
int main()
{
    int m,n,i;
    int A[10000];
    int l=0;
    int h=0;
      
    scanf("%d",&n);
    scanf("%d",&m);
    for(i=0;i<n;i++)
    {
        scanf("%d",&A[i]);
    }
    l=A[0];
    for(i=0;i<n;i++)
    {
        h+=A[i];
        l=l>A[i]?l:A[i];
    }
    while(l<h)
    {
        int mid=(l+h)/2;
        int count=1;
        int temp=0;
          
        for(i=0;i<n;i++)
        {
            temp+=A[i];
            if(temp>mid)
            {
                count++;
                temp=A[i];
            }
        }
        if(count>m)
        {
            l=mid+1;
        }
        else
        {
            h=mid;
        }
          
    }
    printf("%d",l);
  
 }

C++ 解法, 执行用时: 4ms, 内存消耗: 380KB, 提交时间: 2020-08-03

#ifdef debug
#include <time.h>
#endif

#include <math.h>
#include <string.h>

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define MAXN ((int)1e5 + 7)
#define ll long long int
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for (int i = lef; i <= rig; i++)
#define forj(lef, rig) for (int j = lef; j <= rig; j++)
#define fork(lef, rig) for (int k = lef; k <= rig; k++)
#define QAQ (0)

using namespace std;

#define show(x...)                             \
    do {                                       \
        cout << "\033[31;1m " << #x << " -> "; \
        err(x);                                \
    } while (0)

void err() { cout << "\033[39;0m" << endl; }
template <typename T, typename... A>
void err(T a, A... x) {
    cout << a << ' ';
    err(x...);
}

namespace FastIO {

char print_f[105];
void read() {}
void print() { putchar('\n'); }

template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
    x = 0;
    char ch = getchar();
    ll f = 1;
    while (!isdigit(ch)) {
        if (ch == '-') f *= -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    x *= f;
    read(oth...);
}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {
    ll p3 = -1;
    if (x < 0) putchar('-'), x = -x;
    do {
        print_f[++p3] = x % 10 + 48;
    } while (x /= 10);
    while (p3 >= 0) putchar(print_f[p3--]);
    putchar(' ');
    print(oth...);
}
}  // namespace FastIO
using FastIO::print;
using FastIO::read;

int n, m, Q, K, a[MAXN];

int check(int mid) {  //返回最大mid能切割多少块
    int cnt = 0, sum = 0;
    for(int i=1; i<=n; i++) {
        if(a[i] > mid) return true;
        if(sum + a[i] <= mid)
            sum += a[i];
        else {
            cnt ++;
            sum = a[i];
        }
    }
    return cnt >= m; 
}

signed main() {
#ifdef debug
    freopen("test.txt", "r", stdin);
    clock_t stime = clock();
#endif
    read(n, m);
    int lef = 0, rig = 0, mid, ans;
    for(int i=1; i<=n; i++)  {
        read(a[i]);
        lef = max(a[i], lef);
        rig += a[i];
    }
    while(lef < rig) {
        mid = (lef + rig) >> 1;
        int ret = check(mid);
        if(ret) {
            lef = mid + 1;
        } else 
            rig = mid;
    }
    printf("%d\n", lef);

#ifdef debug
    clock_t etime = clock();
    printf("rum time: %lf 秒\n", (double)(etime - stime) / CLOCKS_PER_SEC);
#endif
    return 0;
}

上一题