POJ 3273

【题意描述】

给定一串数据,划分成m段,并把每段内的数据相加,使得m段数据中的最大值最小。

【思路分析】

这里很多人可能考虑用DP,但是会超时。那么根据DP与分治的联系,我们可以联想到运用二分法,对所求最大值进行二分,直到所划分区间的数目等于m段即停止。

这里在确定二分的区间有点技巧,首先low肯定是整个数据的最大值,up是整组数据之和,然后进行逐步二分。不断扩大数据值,使得划分的段数不断减小。

【AC代码】

 1 #include<iostream>
 2 using namespace std;
 3 #define max 100005
 4 int day_cost[max];
 5 int main()
 6 {
 7     int n,m;
 8     while(cin>>n>>m)
 9     {
10         int low=0,up=0;
11         for(int i=0;i<n;i++)
12             {
13                 cin>>day_cost[i] ;
14                 up+=day_cost[i];//寻找二分区间的右端
15                 if(low<day_cost[i])
16                     low=day_cost[i];//寻找二分区间的左端点
17             }
18             int mid;
19          while(low<up)//二分条件 
20          {
21             mid=(low+up)/2;
22             int sum1=0,num=0;
23             for(int i=0;i<n;i++)
24             {
25                 if(sum1+day_cost[i]>mid) 
26                 {num++;
27                 sum1=day_cost[i];
28                 }
29                else  sum1+=day_cost[i];
30             }
31             num++;
32             if(num>m) low=mid+1;//一定加1,否则死循环,造成时间超限!!!
33             else up=mid;
34          }
35         int low_cost=low;//最后的结果是等于最左端数据的
36         cout<<low_cost<<endl;
37     }
38     return 0;
39 }

 

转载于:https://www.cnblogs.com/khbcsu/p/3891871.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值