• P4655 [CEOI2017]Building Bridges


    因为两桥不能相交,故易得(dp)方程:(dp[i]=min{dp[j]+sumw[i-1]-sumw[j]+(h[i]-h[j])^2})

    看起来似乎可以斜率优化,可惜(h[i])不单调。

    这里介绍一种很巧妙的做法:李超线段树。

    整理方程:(dp[i]-h^2[i]-sumw[i-1]=(-2h[j])*h[i]+dp[j]-sumw[j]+h^2[j])

    发现等式右侧的取值是斜率为(-2h[j]),截距为(dp[j]-sumw[j]+h^2[j])的直线。

    相当于我们维护一个直线集,(dp[i])的最小取值即为(h[i])处的最小取值加(h^2[i]+sumw[i-1])

    用李超线段树维护,时间复杂度(O(nlogn))

    代码如下,仅供参考:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int maxn=1e5+10;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    	return x*f;
    }
    int n,h[maxn],sw[maxn],dp[maxn],lim,tr[maxn<<6];
    struct node{int k,b;}p[maxn];
    inline int calc(int id,int pos){
    	if(id==0)return 1e16;
    	return p[id].k*pos+p[id].b;
    }
    inline void update(int h,int l,int r,int x){
    	if(!tr[h])return tr[h]=x,void();
    	int mid=(l+r)>>1;
    	int s=calc(tr[h],mid),t=calc(x,mid);
    	if(l==r){
                    if(s>t)tr[h]=x;
                    return;
            }
    	if(p[tr[h]].k<p[x].k){
    		if(s<t)update(h<<1,l,mid,x);
    		else update(h<<1|1,mid+1,r,tr[h]),tr[h]=x;
    	}else{
    		if(s<t)update(h<<1|1,mid+1,r,x);
    		else update(h<<1,l,mid,tr[h]),tr[h]=x;
    	}
    }
    inline int query(int h,int l,int r,int x){
    	int mid=(l+r)>>1,val=calc(tr[h],x);
    	if(l==r)return val;
    	if(mid>=x)return min(val,query(h<<1,l,mid,x));
    	else return min(val,query(h<<1|1,mid+1,r,x));
    }
    signed main(){
    	n=read();
    	for(int i=1;i<=n;i++){
    		h[i]=read();
    		lim=max(lim,h[i]);
    	}
    	for(int i=1;i<=n;i++)
    		sw[i]=read()+sw[i-1];
    	dp[1]=0;p[1]=(node){-2*h[1],dp[1]-sw[1]+h[1]*h[1]};
    	update(1,0,lim,1);
    	for(int i=2;i<=n;i++){
    		dp[i]=query(1,0,lim,h[i])+sw[i-1]+h[i]*h[i];
    		p[i]=(node){-2*h[i],dp[i]-sw[i]+h[i]*h[i]};
    		update(1,0,lim,i);
    	}
    	printf("%lld
    ",dp[n]);
    	return 0;
    }
    

    深深地感到自己的弱小。

  • 相关阅读:
    转 方法多态与Duck typing;C#之拙劣与F#之优雅
    Steve Jobs explains objectoriented programming
    c# 之 dynamic关键字
    Eric Schmidt 之关于 Steve Jobs
    面向过程vs面向对象
    转 命令,不要去询问(Tell, Don’t Ask)
    转 函数式编程的10年演化:越来越纯
    网络流学习笔记——简单题
    网络流学习笔记——难题
    线性代数学习笔记
  • 原文地址:https://www.cnblogs.com/syzf2222/p/13880781.html
Copyright © 2020-2023  润新知