#include<bits/stdc++.h>
using namespace std;
const int maxm=500;
int k,m,p[maxm];
bool solve(int ans){
int kr=1;
int pre=0;
for(int i=0;i<m;i++){
if(pre+p[i]>ans)
{
kr++;
pre=p[i];
}
else pre+=p[i];
}
return kr<=k;
}
// void print(int ans){
// int pre=0;
// int remain=k;
// int kr=1;
// int last[maxm];
// for(int i=0;i<m;i++){
// if(pre+p[i]>ans|| m-i<remain){
// remain--;pre=p[i];last[i-1]=1;
// }
// else pre+=p[i];
// }
// for(int i=0;i<m-1;i++){
// printf("%d ",p[i]);
// if(last[i]) printf("/ ");
// }
// printf("%d",p[m-1]);
// }
int last[maxm]; // last[i] = 1 iff i is the last book assigned to someone
void print(long long ans) {
long long done = 0;
memset(last, 0, sizeof(last));
int remain = k;
for(int i = m-1; i >= 0; i--) {
if(done + p[i] > ans || i+1 < remain) {
last[i] = 1; remain--; done = p[i];
}
else {
done += p[i];
}
}
for(int i = 0; i < m-1; i++) {
printf("%d ", p[i]);
if(last[i]) printf("/ ");
}
printf("%d\n", p[m-1]);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&m,&k);
int maxn=0 ; //所有p[i]中最值,和求和
int maxr=0;
for(int i=0;i<m;i++){
scanf("%d",&p[i]);
maxn=max(maxn,p[i]);
maxr+=p[i];
}
// 贪心:每次尽量往右划分求是否可以把输入序列划分为2连续值且不超过x,其解定义为p(x);p(x)==1表示可以划分不超过x,否则不成立
// 二分:求解最佳的x值。
while(maxn<maxr){
int M=maxn+(maxr-maxn)/2;
if(solve(M)){
maxr=M;
}
else maxn=M+1;
}
// printf("%d\n",maxn);
print(maxn);
}
return 0;
}
uva 714 贪心+二分
猜你喜欢
转载自blog.csdn.net/qq_38662930/article/details/104239075
今日推荐
周排行