http://acm.hdu.edu.cn/showproblem.php?pid=5933
题意,给出n块价值为a的working blocks,现在要你把他们弄成k块相等的。你有两种操作,把相邻的两块合并,或者把一块拆分成任意价值的两块,问最小操作数是多少。
直接构造即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sum, a[100005], ans;
int main() {
ll T, n, k, Case = 1;
cin >> T;
while(T--) {
sum = 0;
scanf("%I64d%I64d", &n, &k);
for(int i = 0; i < n; i++) {
scanf("%I64d", &a[i]);
sum += a[i];
}
if(sum % k == 0) {
ll ave = sum / k;
ans = 0;
for(int i = 0; i < n; i++) {
if(a[i] < ave) {
for(int j = i + 1; j < n; j++) {
a[i] += a[j];
ans += 1;
if(a[i] == ave) {
i = j;
break;
}
else if(a[i] > ave) {
ans += a[i] / ave;
a[j] = a[i] - a[i] / ave * ave;
if(a[j]) {
i = j - 1;
} else {
i = j;
ans--;
}
break;
}
}
} else if(a[i] > ave) {
ans += a[i] / ave;
a[i] = a[i] - a[i] / ave * ave;
if(a[i])
i = i - 1;
else
ans--;
}
}
printf("Case #%I64d: %I64d\n", Case++, ans);
} else {
printf("Case #%I64d: -1\n", Case++);
}
}
return 0;
}