#include<iostream>
using namespace std;
#define inf 100000000
const int MAX = 505;
int data[MAX];
int isPart[MAX];
int M;
int K;
int calculatePart(int size){
memset(isPart, 0, sizeof(isPart));
int i = M - 1;
int count = 1;
__int64 sum = 0;
while(i >= 0){
if(sum + data[i] > size){
count++;
sum = data[i];
isPart[i] = 1;
}
else
{
sum += data[i];
}
i--;
}
return count;
}
int binaryFind(int min, int max){
int mid = 0;
while(min < max)
{
mid = (min + max) / 2;
if(calculatePart(mid) > K){
min = mid + 1;
}
else
{
max = mid;
}
}
return max;
}
int main()
{
// freopen("1505.txt", "r", stdin);
int testcases = 0;
cin >> testcases;
while(testcases--)
{
cin >> M >> K;
int min = 0;
int max = 0;
int i = 0;
for(i = 0; i < M; i++)
{
cin >> data[i];
if(min < data[i])
min = data[i];
max += data[i];
}
int partNum = binaryFind(min, max);
// cout << partNum << endl;
int part = calculatePart(partNum);
// cout << part << endl;
for(i = 0; i < M - 1 && part < K; i++)
{
if(isPart[i] == 0)
{
isPart[i] = 1;
part++;
}
}
for(i = 0; i < M - 1; i++)
{
cout << data[i] << " ";
if(isPart[i] == 1)
cout << "/ ";
}
cout << data[i] << endl;
}
return 0;
}
解答本题的核心在于利用二分查找的方法,在最小和最大的“段和”间找最合适的哪个“段和”。如果能方便的判断出最合适的“段和”的话,那问题自然就容易解决,关键是需要查找了,二分查找是个不错的选择!最后有点更加重要,把多余的人从前往后安排,已达到最优解决,值得回味啊!说不清楚,看代码即可明白!