XM31. 最优分割
描述
依次给出n个正整数A1,A2,… ,An,将这n个数分割成m段,每一段内的所有数的和记为这一段的权重, m段权重的最大值记为本次分割的权重。问所有分割方案中分割权重的最小值是多少?输入描述
第一行依次给出正整数n,m,单空格切分;(n <= 10000, m <= 10000, m <= n)输出描述
分割权重的最小值示例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; }