1. 求解最优子结构问题,如区间最值、区间和
2. 本质:预处理区间,而后根据要求拼成目的区间,求解问题
3. 例题:
求区间最值RMQ(range maximum/minimum query)
思路:有点像归并排序。递归建树。
存储方法:使用近似满二叉树的储存方法,给每个区间编号,存进数组,利用父子结点的关系遍历。假设给定序列为n个元素,数组大小为4*n-1(满二叉树的结点个数)
int a[n],d[4*n];
void build(int s,int t,int p){//给[s,t]区间建树,结点编号为p
if(s==t){
d[p]=a[s];
return;
}
int m=s+((t-s)/2);//这一步防止溢出
build(s,m,p*2);
build(m+1,t,p*2+1);
}
//bulid(1,n,1);
int getmax(int l,int r,int s,int t,int p){
//查询[l,r] 当前[s,t] 编号p
if(l<=s&&r>=t){
return d[p];
}
//当前区间中存在我不需要的区间,就继续分
int m=s+(t-s)/2,maxans=INT_MIN;
if(l<=m){
maxans=max(maxans,getmax(l,r,s,m,p*2));//左子节点
}
if(r>m){
maxans=max(maxans,getmax(l,r,m+1,t,p*2+1));//右子节点
}
return maxans;
}