您的位置:首页 > 其它

二分、三分总结

2014-12-18 16:52 316 查看
简单描述

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

应用

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
,b
;
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
=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,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;
}


三分

应用

查找可以被分割成小于或等于两个单调性区间的抛物线的临界值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 POJ 应用