您的位置:首页 > 其它

bzoj2369 && 2687 -- 决策单调性优化DP

2017-10-07 13:27 666 查看
显然只选 2 个区间是最优的,因为取一个集合中所有区间一定没有只取最左和最右两个区间优。

对于那些有包含关系的区间,更新一下答案,只留下最大的区间就可以了。

将区间按左端点排序。

设第 i 个区间为 [li,ri] 。可以发现若 p<k<i<j ,且对于 i 来说 k 比 p 优,那么对于 j 来说 k 也比 p 优。

证明如下:

(ri−lk)(rk−li)>(ri−lp)(rp−li)

ri(rk−rp)+li(lk−lp)>lkrk−lprp

由于 l 和 r 都是单调递增的 , 所以

rj(rk−rp)+lj(lk−lp)>lkrk−lprp

(rj−lk)(rk−lj)>(rj−lp)(rp−lj)

所以对于 j 来说 k 比 p 优。

由于不用在线,可以用分治做决策单调性。注意判断两个区间是否有交。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
char c=nc();
for(;c<'0'||c>'9';c=nc());
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define N 1000010
#define ll long long
struct Node{
int l,r;
}a
,b
;
int i,j,k,n,m,p,mx,x;
ll Ans;
inline bool Cmp(Node a,Node b){
if(a.l==b.l)return a.r>b.r;
return a.l<b.l;
}
inline void Solve(int l,int r,int L,int R){
if(l>r)return;
int Mid=l+r>>1,x=0;
ll mx=0;
for(int i=min(R,Mid-1);i>=L&&b[i].r>b[Mid].l;i--){
ll t=1ll*(b[Mid].r-b[i].l)*(b[i].r-b[Mid].l);
if(t>mx)mx=t,x=i;
}
Ans=max(Ans,mx);
if(!x)Solve(l,Mid-1,L,R),Solve(Mid+1,r,L,R);else
Solve(l,Mid-1,L,x),Solve(Mid+1,r,x,R);
}
int main(){
Read(n);
for(i=1;i<=n;i++)Read(a[i].l),Read(a[i].r);
sort(a+1,a+n+1,Cmp);
mx=a[1].r;x=1;
b[m=1]=a[1];
for(i=2;i<=n;i++)
if(a[i].r>mx)mx=a[i].r,b[++m]=a[i],x=i;else
Ans=max(Ans,1ll*(a[i].r-a[i].l)*(a[x].r-a[x].l));
Solve(2,m,1,m);
cout<<Ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: