• 【DP、线段树优化】琪露诺


    跟去年(2017)PJ第四题几乎是一样的?/吐血

    DP方程可以很简单的推出来,f[i]=max{f[k]}+a[i]

    然而这样做是O(n^2)的

    看一下数据,200000的话要不nlogn 要不n

    由于题解里面单调队列和优先队列都有人用了,那就来一发线段树

    (或者实情是:单调队列不会打?)

    只要维护i-r~i-l中f[i]的区间最大值即可(单点修改-区间查询)

    40行AC

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read(){
    	int ans=0,f=1; char chr=getchar();
    	while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
    	while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
    	return ans*f;
    }
    int f[200005],n,a[200005],l,r,ans;
    int maxn[200005<<2];
    void updata(int i,int l,int r,int pos,int x){
    	if(l==r){maxn[i]=x;return;}
    	int mid=l+r>>1;
    	if(pos<=mid) updata(i<<1,l,mid,pos,x);
    	else updata(i<<1|1,mid+1,r,pos,x);
    	maxn[i]=max(maxn[i<<1],maxn[i<<1|1]);
    }
    int query(int i,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr){return maxn[i];}
    	int mid=l+r>>1,x=-0x3f3f3f3f,y=-0x3f3f3f3f;
    	if(ql<=mid) x=query(i<<1,l,mid,ql,qr) ;
    	if(qr>mid) y=query(i<<1|1,mid+1,r,ql,qr);
    	return max(x,y);
    }
    int main(){
    	n=read();l=read(),r=read();
    	for(int i=0;i<=n;i++)a[i]=read();
    	for(int i=0;i<=l;i++)	f[i]=0;
    	for(int i=l+1;i<=n;i++){
    		f[i]=max(f[i],query(1,1,n,max(0,i-r),i-l)+a[i]);
    		updata(1,1,n,i,f[i]);
    	}
    	for(int i=n-r;i<=n;i++)
    		ans=max(f[i],ans);
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    jQuery的版本兼容问题
    web页面锁屏初级尝试
    mvc5之文件上传
    魔方基础入门教程
    XCube和X组件的入门级使用教程
    蔬菜大棚监控与管理 1.0版本(未完善)
    蔬菜大棚 数据库设计 0.5版本()
    记录一段存储过程
    MPU9250九轴陀螺仪--读接口数据
    MPU9250九轴陀螺仪--连接MPU9250
  • 原文地址:https://www.cnblogs.com/zhenglw/p/9904474.html
Copyright © 2020-2023  润新知