[BZOJ 1233][Usaco2009Open]干草堆tower:单调队列

来源:互联网 发布:cs6色环插件mac 编辑:程序博客网 时间:2024/05/18 01:59

点击这里查看原题

f[i]表示i~n堆叠成的最底层边的最小值,f[i]=min { sum[j-1]-sum[i-1] } ( i < j 且 sum[j-1]-sum[i-1]>=f[j] )
对于i < j < k,j一定比k更优,如果只能选k,则说明j不满足条件,k满足条件。即,f[j] - sum[j-1]>f[k] - sum[k-1]

/*User:SmallLanguage:C++Problem No.:1233*/#include<bits/stdc++.h>#define ll long long#define inf 999999999using namespace std;const int M=1e5+5;int ans,sum[M],f[M],g[M],q[M],h,t,n;int main(){    freopen("data.in","r",stdin);//    scanf("%d",&n);    for(int i=1;i<=n;i++){        int x;        scanf("%d",&x);        sum[i]=sum[i-1]+x;    }    h=t=1;    q[1]=n+1;    for(int i=n;i;i--){        while(h<t&&sum[q[h+1]-1]-sum[i-1]>=f[q[h+1]]) h++;        f[i]=sum[q[h]-1]-sum[i-1];        g[i]=g[q[h]]+1;        while(h<t&&f[i]-sum[i-1]<f[q[t]]-sum[q[t]-1]) t--;        q[++t]=i;    }    printf("%d\n",g[1]);    return 0;}
0 0
原创粉丝点击