poj-3273 Monthly Expense 二分
题意是给出n天的每一天的钱,求将这些钱按照顺序分为m组,使得每一组的钱尽量少,并且输出分组后钱最多的那一组的钱数。
参考了http://blog.csdn.net/change_ac/article/details/50755213
1. 分组后的每一组的最大的钱一定大于等于全部钱的最大值,小于等于钱的总和,由此得到最初的high和low
2.那就在所得到的范围内一个个试,看哪一个符合条件,但不是盲目试,而是用二分查找
3. 二分查找(suit),如果按照这个数(mid) 来分组,而分得的组比m大,则mid要大一点,反之mid 要小一点
4.最后得到应该有low==high 所以mid=(low+high)/2就是最终答案
#include <iostream>
using namespace std;
int n,m,a[100000];
int suit(int mid)
{
int sum=0,group=1;
for(int i=0;i<n;i++)
{
sum+=a[i];
if(sum>mid)
{
sum=a[i];
group++;
}
}
if(group>m) return 1;
else return 0;
}
int main() {
int high=0,low=0,mid;
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>a[i];
high+=a[i];
low=a[i]>low?a[i]:low;
}
while(low<high)
{
mid=(low+high)/2;
if(suit(mid)) low=mid+1;
else high=mid-1;
}
mid=(high+low)/2;
cout<<mid<<endl;
return 0;
}
二分题还有poj2785 3258 hdu1969 对于(直接或间接)给出范围之后在范围内找某个数,应该想到二分查找