poj 3273 Monthly Expense(贪心+二分)

题目:http://poj.org/problem?id=3273

题意:把n个数分成m份,使每份的和尽量小,输出最大的那一个的和。

思路:二分枚举最大的和,时间复杂度为O(nlog(sum-max));

一道很好的题。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn = 100000+10;
 8 int a[maxn];
 9 
10 int main()
11 {
12     int n, m, i, Max, sum;
13     while(~scanf("%d%d", &n, &m))
14     {
15         Max = -1;
16         sum = 0;
17         for(i = 0; i < n; i++)
18         {
19             scanf("%d", &a[i]);
20             sum += a[i];
21             if(Max < a[i])
22             Max = a[i];
23         }
24         int high = sum, low = Max, mid;
25         while(high>low)
26         {
27             mid = (high+low)/2;
28             int cou = 1, w = 0;
29             for(i = 0; i < n; i++)
30             {
31                 w += a[i];
32                 if(w>mid)
33                 {
34                     cou++;  //cou记录最大值为mid的情况下,可以分成几份
35                     w = a[i];
36                 }
37             }
38             if(cou>m)
39             low = mid+1;
40             else
41             high = mid-1;
42         }
43         printf("%d\n", high);
44     }
45     return 0;
46 }

 

 

以后还是用这种形式的二分吧

while(left<right)

{

if()

left=mid+1;

else right=mid;

}

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn = 100000+10;
 8 int a[maxn];
 9 
10 int main()
11 {
12     int n, m, i, Max, sum;
13     while(~scanf("%d%d", &n, &m))
14     {
15         Max = -1;
16         sum = 0;
17         for(i = 0; i < n; i++)
18         {
19             scanf("%d", &a[i]);
20             sum += a[i];
21             if(Max < a[i])
22             Max = a[i];
23         }
24         int high = sum, low = Max, mid;
25         while(high > low)
26         {
27             mid = (high+low)/2;
28             int cou = 1, w = 0;
29             for(i = 0; i < n; i++)
30             {
31                 w += a[i];
32                 if(w>mid)
33                 {
34                     cou++;
35                     w = a[i];
36                 }
37             }
38             if(cou <= m)
39             high = mid;
40             else
41             low = mid+1;
42         }
43         printf("%d\n", low);
44     }
45     return 0;
46 }

 

 

posted @ 2014-03-13 21:07  水门  阅读(196)  评论(0编辑  收藏  举报