二分、三分总结

9 篇文章 0 订阅
6 篇文章 0 订阅

简单描述

在决策过程中,使得达到平衡度高。常常因为我们的算法是要解决一类问题,一个好的算法往往要考虑的却是最坏的情况。对于二分,我们要做的是选择出期望值,其实可以想想每次最多能排除多少可以可能值。


应用

1、必须具有单调性

2、把决策问题转化为判定性问题,来解决最优化问题


A:查找某个正确的结果

B:查找某个值的的区间

C:二分逼近求根号

D:对于二维有序数组,可以二分在嵌套二分

E:对于多维可以多次嵌套

F:青蛙过河问题,给定河宽L,n个石墩,最多用m步,求每一步最少跳多远,能跳过河。点击打开HDU题目链接

#include <iostream>
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500005
using namespace std;
int L,n,m,a[N],b[N];
int get_ans( int x )
{
    if( x<b[0]) return -1;
    int sum=0,num=0;
    for( int i=0; i<=n; i++ )
    {
        if ( b[i] > x ) return -1;
        sum+=b[i];
        if( sum>x )
        {
            num++;
            sum=b[i];
        }
        if( num>=m ) return -1;
    }
    if( sum>x )num+=2;
    else if ( sum > 0 ) num++;
    if( num>m ) return -1;
    else return 1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while( cin>>L>>n>>m )
    {
        for( int i=0; i<n; i++ )
        {
            scanf("%d",&a[i]);
        }
        sort(a,a+n);
        b[0]=a[0];
        for(int i=1; i<n; i++ )
        {
            b[i]=a[i]-a[i-1];
        }
        b[n]=L-a[n-1];
        int mid,l=b[0]-1,r=L+6;
        while( l<=r )
        {
            mid = (l+r)/2;
            int t = get_ans(mid);
            if( t==-1 ) l=mid+1;
            else r=mid-1;
        }
        printf("%d\n",r+1);
    }
    return 0;
}


G:给你n个数,让分成m个连续的组,求在分得组中,使得组和的最大值最小。poj 题目链接

#include<cstdio>
#define N 100010
using namespace std;
int a[N],n,m;

int work(int left,int right)
{
    int mid;
    while(left<=right)
    {
        mid=left+(right-left)/2;
        int sum=0,temp=0;
        bool flag=true;
        for(int i=0;i<n;i++)
        {
            if(mid<temp+a[i])
            {
                temp=a[i];
                sum++;
                if(sum>=m)
                {
                    if(i+1==n&&sum==m)flag=true;
                    else flag=false;
                    break;
                }
            }
            else temp+=a[i];
        }

        if(!flag)left=mid+1;
        else right=mid-1;
    }
    return mid;
}
int main()
{
    int i,j,mx=0;
    int sum=0;
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];
        if(a[i]>mx) mx=a[i];
    }
    printf("%d\n",work(mx,sum));
    return 0;
}


三分

应用

查找可以被分割成小于或等于两个单调性区间的抛物线的临界值


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值