标签:style color 使用 os io for 问题 ar
题意:k份书稿分成m份,使得每份的和最小
思路:典型最大值最小化问题,使用贪心+二分。贪心的是每次尽量将元素往右边划分,二分查找最小的x满足m个连续的子序列和S(i)都不超过x。
因为输出的原因,在划分时就从后往前尽量划分。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int MAXN = 1005; int m, k, t; int arr[MAXN], vis[MAXN]; ll ans, sum, Min; int judge(ll x) { memset(vis, 0, sizeof(vis)); ll s = 0; t = 0; int flag = 1; for (int i = m - 1; i >= 0; i--) { if (arr[i] > x) { flag = 0; break; } if (s + arr[i] > x) { vis[i] = 1; t++; s = arr[i]; if (t > k - 1) { flag = 0; break; } } else s += arr[i]; } return flag; } int binary() { ll x = Min, y = sum; while (x < y) { ll mid = x + (y - x) / 2; if (judge(mid)) y = mid; else x = mid + 1; } return x; } void outPut() { judge(ans); int num = k - 1 - t; for (int i = 0; i < m; i++) { if (vis[i] == 0 && num) { vis[i] = 1; num--; } } for (int i = 0; i < m - 1; i++) { printf("%d ", arr[i]); if (vis[i]) printf("/ "); } printf("%d\n", arr[m - 1]); } int main() { int cas; scanf("%d", &cas); while (cas--) { scanf("%d %d", &m, &k); ans = 0; Min = arr[0]; for (int i = 0; i < m; i++) { scanf("%d", &arr[i]); sum += arr[i]; if (Min < arr[i]) Min = arr[i]; } ans = binary(); outPut(); } return 0; }
UVA714- Copying Books(最大值最小化),布布扣,bubuko.com
标签:style color 使用 os io for 问题 ar
原文地址:http://blog.csdn.net/u011345461/article/details/38313023