最大值最小化,第一反应是Convex Optimization,想起了拉格朗日乘子法和对偶性哈哈哈
Rujia这个不断压低上限的做法,又让我想起了EM算法(其实完全不是一个东西吧)
这道题需要注意几点:
1、书的顺序是不能改变的。
2、RE有可能是因为整型溢出。每道题都必须仔细检查所有可能溢出的地方
3、好好照顾循环的出入口、妥善处理循环跳出后还没有处理的数据(例如归并排序的循环结束后)
Run Time: 0.016s
#define UVa "LT8-10.714.cpp"
char fileIn[30] = UVa, fileOut[30] = UVa;
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
//Global Variables. Reset upon Each Case!
const long long maxn = 1000;
long long m, k;
long long books[maxn];
/
int P(long long x) {
long long groups = 1;
long long sum = 0;
for(long long i = 0; i < m; i ++) {
if(books[i] > x) return 0;
if(sum + books[i] > x) {
groups ++;
sum = 0;
}
sum += books[i];
}
if(sum > x) {
groups ++;
}
if(groups > k) return 0;
return 1;
}
int main() {
int N;
scanf("%d", &N);
for(int kase = 0; kase < N; kase ++) {
scanf("%d%d", &m, &k);
for(long long i = 0; i < m; i ++) scanf("%d", &books[i]);
long long l = 0;
long long r = 5000000010L;
while(l < r) {
long long mid = l + (r-l)/2;
if(P(mid)) {
r = mid;
}
else {
l = mid + 1;
}
}
vector<int> ans[maxn]; //one vector per scriber
long long sum = 0;
long long cur_scriber = k-1;
long long cur_book;
for(cur_book = m-1; cur_book >= 0; cur_book --) {
if(sum + books[cur_book] > l) {
sum = 0;
cur_scriber --;
}
if(cur_book == cur_scriber) { //one book per scriber.
for(int i = 0; i <= cur_book; i ++) ans[i].push_back(books[i]);
break;
}
ans[cur_scriber].push_back(books[cur_book]);
sum += books[cur_book];
}
for(long long i = 0; i < k; i ++) {
for(long long j = ans[i].size()-1; j >= 0; j --) {
if(j != ans[i].size()-1) printf(" ");
printf("%d", ans[i][j]);
}
if(i!=k-1)printf(" / ");
}
printf("\n");
}
return 0;
}