Poj 3017 Cut the Sequence (DP,单调队列优化,数据结构优化)

来源:互联网 发布:c语言国际象棋棋盘 编辑:程序博客网 时间:2024/06/05 23:01

题目链接:poj 3017

论暴力姿势的优雅性。
这道题直接用单调队列的大暴力居然过了,而且跑得很快。正解的话应该是用数据结构维护。时间复杂度为NlogN。

先粘一个用单调队列优化的DP

#include<cstdio>#include<cstring>#include<iostream>using namespace std;#define LL long long#define inf (1e18)const int maxn=100000+10;LL N,M;LL a[maxn],q[maxn];LL f[maxn],sum[maxn];inline LL read(){LL x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}void input(){N=read(); M=read();for(int i=1;i<=N;i++){a[i]=read(); sum[i]=sum[i-1]+a[i];}}void solve(){for(int i=1;i<=N;i++)f[i]=inf;int L=1,R=1,col=0,t=0;q[1]=1;f[1]=a[1]; f[0]=0;for(int i=2;i<=N;i++){while(i>t && sum[i]-sum[t]>M)t++;if(t==i){col=1; break;}while(L<=R && a[i]>=a[q[R]])R--;q[++R]=i;while(L<=R && sum[i]-sum[q[L]-1]>M)L++;f[i]=f[t]+a[q[L]];for(int j=L;j<R;j++){f[i]=min(f[i],f[q[j]]+a[q[j+1]]);}}if(col)printf("-1");else cout<<f[N]<<endl;}int main(){input();solve();return 0;}

至于作死的数据结构优化什么的,我到现在还没有看懂罗雨屏讲的用线段树来优化的。先挖一个坑,之后填。

0 0