二分、三分算法
二分
二分是在一个单调有序的集合中查找一个解,因为每次查找将舍弃一半的空间,因此效率很高i。
三分
三分算法用于求解单峰函数的极值问题。
例题1
二分
题目:Monthly Expense
地址:POJ3273
思路:答案一定是a[i]中最大的数到a[i]的总和之间的某个数。二分查找符合题意的最小结果即可
查找范围【max(a[i]),sum(a[i])】 符合题意的条件:分为每组不超过t的组数不多与题目要求的组数
Code
#include <iostream>
using namespace std;
int n,m;
int a[100100];
bool check(int max)
{
int sum=0;
int group=1;
for(int i=1;i<=n;i++)
{
if(sum+a[i]<=max)
{
sum+=a[i];
}else
{
group++;
sum=a[i];
}
}
return (group<=m); 组数少于于m组时可以将任意一组拆分
}
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
while(cin>>n>>m)
{
int sum=0,ma=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
ma=max(ma,a[i]); 每组至少有一个数,所以最小的结果一定不小于a[i]的最大值
}
int l=ma,r=sum,mid;
while(l!=r)
{
mid=(l+r)/2;
if(check(mid))
{
r=mid;
}else
{
l=mid+1;
}
}
cout<<l<<endl;
}
return 0;
}