zoukankan      html  css  js  c++  java
  • POJ3017

    题意

       将一段序列分割为任意段,每一段的连续和不超过M,使得每一段最大值的和最小.

    分析

       用单调队列进行优化的dp。单调队列可以维护可以影响当前区间的最大值。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <queue>
     6 using namespace std;
     7 const int maxn=100000+100;
     8 int a[maxn];
     9 long long f[maxn];
    10 long long sum[maxn];
    11 int n;
    12 long long m;
    13 int main(){
    14     scanf("%d%lld",&n,&m);
    15     sum[0]=0;
    16     int ok=1;
    17     for(int i=1;i<=n;i++){
    18         scanf("%d",&a[i]);
    19         sum[i]=sum[i-1]+a[i];
    20         if(a[i]>m)ok=0;
    21     }
    22     if(!ok){printf("-1");return 0;}
    23     f[0]=0;
    24     f[1]=a[1];
    25     deque<int>q;
    26     int beg=1;
    27     for(int i=1;i<=n;i++){
    28             while(!q.empty()&&a[i]>=a[q.back()])q.pop_back();
    29             while(sum[i]-sum[beg-1]>m&&beg<i)beg++;
    30             q.push_back(i);
    31             while(q.front()<beg&&!q.empty())q.pop_front();
    32             f[i]=f[beg-1]+a[q.front()];
    33             for(int k=1;k<=q.size();k++){
    34                 int b=q.front();
    35                 q.pop_front();
    36                 if(!q.empty())
    37                 f[i]=min(f[i],f[b]+a[q.front()]);
    38                 q.push_back(b);
    39             }
    40     }
    41     printf("%lld",f[n]);
    42 return 0;
    43 }
    View Code
  • 相关阅读:
    独立人格,让人生更美好
    版本控制入门简介
    Android蓝牙操作
    Android Rect和RectF的区别
    做个环保主义的程序员
    java/android下JNI编程总结
    别太单纯,也别太不单纯
    C++ namespace的用法
    JNI编程
    企业架构 - 架构原则
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/8825074.html
Copyright © 2011-2022 走看看