POJ 3273 Monthly Expense 二分穷举

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

题意:给出农夫在n天中每天的花费,要求把这n天分作m组,每组的天数必然是连续的,要求分得各组的花费之和应该尽可能地小,最后输出各组花费之和中的最大值

思路:这个花费的最大值一定介于所有值的和与所有天数中最大的哪一个。直接让l = maxday ,r = sum然后取中值,枚举,从第一天开始,如果现在的金钱大于mid,那么组数就+1这样就检查组数即可,假设是小于,说明这个mid值明显偏大。这样即可找出答案

代码:

View Code
 1 #include <stdio.h>
 2 #include <iostream>
 3 using namespace std;
 4 #define N  100050
 5 int mon[N];//每天的钱
 6 int n,m;
 7 int low_or_high(long mid,int m)
 8 {
 9     int i;
10     int num_group;
11     long sum_now;
12     sum_now = 0;
13     num_group = 0;
14     for(i = 0;i < n;i++)
15     {
16 
17         if(mid < sum_now+mon[i])//如果满足了mid组数+1
18         num_group++,sum_now = mon[i];
19         else
20         sum_now += mon[i];
21     }
22 
23     if(num_group < m)
24     return 0;
25 
26     return 1;
27 }
28 int main()
29 {
30    // int n,m;
31     while(cin>>n>>m)
32     {
33         int i;
34         long high,low;
35         high = 0;
36         low = 0;
37         for(i = 0;i < n;i++)
38         {
39             cin>>mon[i],high+=mon[i];
40             if(low < mon[i])
41             low = mon[i];
42         }
43         long mid;
44         mid = (high+low)/2;
45 
46         while(low < high)
47         {
48 
49             if(low_or_high(mid,m))
50             low = mid+1;
51             else
52             high = mid-1;
53             mid = (low+high)/2;
54         }
55         cout<<mid<<endl;
56     }
57     return 0;
58 }

 

posted @ 2013-03-27 15:43  某某。  阅读(187)  评论(0编辑  收藏  举报