UVa 714 - Copying Books

  题目大意:有m本书,每本书有pi页,把这m本书分给k个人抄写,如何分配才能在最短的时间抄写完这m本书。

  最大值最小化问题:把一个包含n个正整数的序列划分成m个连续的子序列,设第i个序列的各数之和为S(i), 使得所有S(i)的最大值尽量小。序列最大值为max,所有数之和为sum,则所求答案必定在[max, sum]之间,通过二分法判断中值mid是否符合条件(把序列分为m份,每份均不超过mid)逐步缩小范围,直至求得解。

  其实,我觉得还是看代码来的直接,看书上说的东西半天也不理解说的什么意思,还是研究代码可以一点点地理解。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define MAXN 500+10
 6 
 7 long long p[MAXN];
 8 int m, k;
 9 bool cut[MAXN];
10 
11 bool judge(long long n)
12 {
13     long long sum = 0;
14     int cnt = 0;
15     for (int i = 0; i < m; i++)
16     {
17         if (sum + p[i] > n)
18         {
19             sum = 0;
20             cnt++;
21         }
22         sum += p[i];
23     }
24     cnt++;
25     if (cnt > k)  return false;
26     return true;
27 }
28 
29 int main()
30 {
31 #ifdef LOCAL
32     freopen("in", "r", stdin);
33 #endif
34     int T;
35     scanf("%d", &T);
36     while (T--)
37     {
38         scanf("%d%d", &m, &k);
39         long long sum = 0, lmax = 0;
40         for (int i = 0; i < m; i++)
41         {
42             scanf("%lld", &p[i]);
43             sum += p[i];
44             lmax = max(lmax, p[i]);
45         }
46         long long low = lmax, high = sum;
47         while (low < high)
48         {
49             long long mid = (low + high) / 2;
50             if (judge(mid))  high = mid;
51             else  low = mid + 1;
52         }
53         long long ans = low;
54         int remain = k - 1;
55         memset(cut, 0, sizeof(cut));
56         sum = 0;
57         for (int i = m-1; i >= 0; i--)
58         {
59             if (i+1 > remain && sum + p[i] <= ans)
60             {
61                 sum += p[i];
62             }
63             else
64             {
65                 cut[i] = true;
66                 sum = p[i];
67                 remain--;
68             }
69         }
70         for (int i = 0; i < m; i++)
71         {
72             printf("%lld%s", p[i], (i == m-1) ? "\n" : " ");
73             if (cut[i])  printf("/ ");
74         }
75     }
76     return 0;
77 }
View Code

  最后的输出把我纠结地快疯了,本来也不是很麻烦,可是因为参考别人代码一会就把自己弄迷糊了,果然有些东西还是按自己思路写更自然、快速。

posted @ 2013-08-22 16:54  xiaobaibuhei  阅读(358)  评论(0编辑  收藏  举报