LightOJ - 1048 Conquering Keokradong(贪心)

来源:互联网 发布:好的外文数据库 编辑:程序博客网 时间:2024/06/06 11:46

题目大意:要求你将N个数分成k + 1个区间,使得每个区间的和的最大值最小

解题思路:最大值最小,二分解决

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 1010;int n, k, l, r, cas = 1;int x[N];void init() {    scanf("%d%d", &n, &k);    r = 0, l = 0;    for (int i = 0; i <= n; i++) {        scanf("%d", &x[i]);        l = max(x[i], l);        r += x[i];    }    n++;}bool judge(int mid) {    int cur = 0, day = 0;    for (int i = 0; i < n; i++) {        if (cur + x[i] > mid) {            cur = x[i];            day++;        }        else {            cur += x[i];        }    }    return day <= k;}void solve() {    while (l <= r) {        int mid = (l + r) >> 1;        if (judge(mid)) r = mid - 1;        else l = mid + 1;    }    int Min = r + 1;    printf("Case %d: %d\n", cas++, Min);    int day = 0, i, way = 0;    for (i = 0; i < n; i++) {        if (way + x[i] > Min) {            printf("%d\n", way);            way = x[i];            day++;        }        else way += x[i];        if (k - day == n - i - 1) {            printf("%d\n", way);            break;        }    }    if (i == n) printf("%d\n", way);    else {        for (i = i + 1; i < n; i++)            printf("%d\n", x[i]);    }}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击