二分加贪心
这道题可以自己预先设置一个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);
}
}