Uva714

来源:互联网 发布:java正则表达式 匹配: 编辑:程序博客网 时间:2024/05/16 11:21

二分加贪心

这道题可以自己预先设置一个x 使得所有的是S(i) 均小于这个x 而x的求法可以通过二分法求得 最后贪心输出解

#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int maxn = 600;int n, m, k,maxp;long long  tot;int arr[maxn],last[maxn];int solve(long long maxn){    int ans = 1;    long long done = 0;    for (int i = 0; i < m; i++)    {        if (done + arr[i] <= maxn)            done += arr[i];        else        {            ans++;            done = arr[i];        }    }    return ans;}void print(long long ans){    memset(last, 0, sizeof(last));    long long done = 0;    int remain = k;    for (int i = m - 1; i >= 0; i--)//贪心输出解 从后面往前面标记    {        if (done + arr[i] > ans || i + 1 < remain)//当和超过ans或者剩余数据个数小于设定的k时进行标记        {            last[i] = 1;            remain--;            done = arr[i];        }        else        {            done += arr[i];        }    }    for (int i = 0; i < m-1; i++)    {        cout << arr[i] << " ";        if (last[i])            cout << "/ ";    }    cout << arr[m - 1] << endl;}int main(){    cin >> n;    while (n--)    {        cin >> m >> k;        tot = 0;        maxp = -1;        for (int i = 0; i < m; i++)        {            cin >> arr[i];            tot += arr[i];            maxp = max(maxp, arr[i]);          }        long long L = maxp, R = tot;        while (L < R)//二分法求x        {            long long m = L + (R - L) / 2;            if (solve(m) <= k)            {                R = m;            }            else            {                L = m + 1;            }                   }        print(L);    }}