分治的基本概念:
把一个任务,分成形式和原任务相同,但规模更小的几个部分任务(通常是两个部分),分别完成,或只需要选一部完成。然后再处理完成后的这一个或几个部分的结果,实现整个任务的完成。
步骤
1.分解
将原问题分解为若干规模较小,相互独立,与原问题相同的子问题。
2.解决
若干子问题较小而容易被解决则直接解决,否则再继续分解为更小的子问题,直到容易解决。
3.合并
将已求解的各个子问题的解,逐步合并为原问题的解。
有的问题分解后不需要合并子问题的解,此时就不需要再做第3步了。多数问题需要子问题的解,按照题意使用恰当的方法合并成为整个问题的解。需要具体问题具体分析。
生活实例:
称硬币
16硬币,有可能有1枚假币,假币比真币轻。有一架天
平,用最少称量次数确定有没有假币,若有的话,假
币是哪一枚。
8-8的称——挑出轻的那一堆
4-4的称——挑出轻的那一堆
..........
典型例题:
求最大子数组和:
#include<stdio.h>
#include<stdlib.h>
int max3(int a,int b,int c)
{
int max;
max=a>b?a:b;
max=max>c?max:c;
return max;
}
int maxai(int a[],int l,int r)
{
int mid;
int maxleft,maxright;
int maxboderleft,maxboderright;
int leftboder,rightboder;
if(l==r)
{
if(a[l]>0)
return a[l];
else
return 0;
}
mid=(l+r)/2;
maxleft=maxai(a,l,mid);
maxright=maxai(a,mid+1,r);
leftboder=0,rightboder=0;
maxboderleft=0,maxboderright=0;
for(int i=mid;i>=l;i--)
{
leftboder+=a[i];
if(leftboder>maxboderleft)
maxboderleft=leftboder;
}
for(int i=mid+1;i<=r;i++)
{
rightboder+=a[i];
if(rightboder>maxboderright)
maxboderright=rightboder;
}
return max3(maxleft,maxright,maxboderleft+maxboderright);
}
int main()
{
int n;
scanf("%d",&n);
int a[n]={0};
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int l=0,r;
r=n-1;
int sum=maxai(a,l,r);
printf("%d",sum);
return 0;
}