洛谷 P1714 切蛋糕(dp+RMQ)

来源:互联网 发布:腾讯视频下载mac版 编辑:程序博客网 时间:2024/05/17 01:59

传送门
首先,很简单的dp方程:

fi=max(sisj)(j[im,i])
然后发现sij无关,可以提出来:
fi=simin(sj)(j[im,i])
发现这个方程可以用数据结构优化,比如线段树,树状数组等等,我这里推荐用st表。
预处理:O(nlogn) 递推:O(n)
代码:

#include<bits/stdc++.h>#define ll long longusing namespace std;inline int read(){    int x=0;char ch=' ';int f=1;    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();    if(ch=='-')f=-1,ch=getchar();    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();    return x*f;}int n,m;int a[500001];int s[500001];int st[20][500001];inline int query(int l,int r){    int k=log(r-l+1)/log(2);    return min(st[k][l],st[k][r-(1<<k)+1]);}int main(){    Log[0]=-1;    for(int i=1;i<=n;i++){        Log[i]=Log[i>>1]+1;    }    n=read();m=read();    for(int i=1;i<=n;i++){        a[i]=read();        s[i]=s[i-1]+a[i];        st[0][i]=s[i];    }    for(int k=1;k<=19;++k){        for(int i=1;i+(1<<k)-1<=n;++i){            st[k][i]=min(st[k-1][i],st[k-1][i+(1<<(k-1))]);        }    }    int ans=-0x7fffffff;    for(int i=1;i<=n;++i){        int l=i-m;        if(l<0)l=0;        int num=s[i]-query(l,i);        ans=max(ans,num);    }    printf("%d",ans);    return 0;}
原创粉丝点击