http://poj.org/problem?id=3017
dp+单调队列
算法的理论时间复杂度应该还是接近 O(n^2) 但为什么过得还挺快呢 应该是后台数据的问题吧
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<map> #include<vector> #include<stack> #include<set> #include<map> #include<queue> #include<deque> #include<algorithm> #include<cmath> #define LL long long //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int INF=0x3f3f3f3f; const int N=400005; LL a[N]; int n; LL m,ans[N]; int dq[N],il,ir; int main() { //freopen("data.in","r",stdin); scanf("%d %I64d",&n,&m); for(int i=1;i<=n;++i) scanf("%I64d",&a[i]); for(int i=1;i<=n;++i) if(a[i]>m) {printf("-1\n");return 0;} il=0;ir=-1; LL sum=0; a[0]=0; ans[0]=0; int l=1; for(int i=1;i<=n;++i) { while(il<=ir&&a[dq[ir]]<=a[i]) --ir; dq[++ir]=i; sum+=a[i]; while(sum>m) { sum-=a[l]; ++l; } while(dq[il]<l) {++il;} if(l==1) {ans[i]=a[dq[il]];continue;} ans[i]=ans[l-1]+a[dq[il]]; for(int j=il;j<ir;++j) { int k=dq[j]; ans[i]=min(ans[i],ans[k]+a[dq[j+1]]); } } printf("%I64d\n",ans[n]); return 0; }