poj 3273 Monthly Expense (二分搜索,最小化最大值)
题目:http://poj.org/problem?id=3273
思路:通过定义一个函数bool can(int mid):=划分后最大段和小于等于mid(即划分后所有段和都小于等于mid)
这样我们转化为求 满足该函数的 最小mid。即最小化最大值,可以通过二分搜索来做,要注意二分的边界。WR了好几次。
代码:
#include<iostream> #include<string> #include<cstdlib> #include<cstdio> using namespace std; const int MAXN=100005; int N,M,money[MAXN]; bool can(int mid) //判断值 mid 是否满足划分M段后 每段最大和的最小值小于等于mid { int sum=0,cnt=0; for(int i=0;i<N-1;i++) { sum+=money[i]; if(sum+money[i+1]>mid) { cnt++; sum=0; } } if(cnt>M-1)return 0; else return 1; } int main() { while(cin>>N>>M) { int lhs=0,rhs=0; for(int i=0;i<N;i++) { scanf("%d",&money[i]); lhs=max(lhs,money[i]); //下届 rhs+=money[i]; //上届 } if(M==1) { cout<<rhs<<endl; // 不划分则输出所有元素的和 continue; } while(lhs<rhs) { int mid=(lhs+rhs)>>1; if(can(mid))rhs=mid; else lhs=mid+1; } cout<<lhs<<endl; } return 0; }