二分/三分算法

二分、三分算法

二分

二分是在一个单调有序的集合中查找一个解,因为每次查找将舍弃一半的空间,因此效率很高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;
}

猜你喜欢

转载自blog.csdn.net/qq_30445397/article/details/106149858
今日推荐