[POJ 3017] Cut the Sequence

[题目链接]

           http://poj.org/problem?id=3017

[算法]

        multiset + dp + 单调队列

[代码]

        

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;
#define MAXN 100010

int i,n,l,r,pos;
multiset< long long > s;
int a[MAXN];
long long f[MAXN],q[MAXN];
long long m,cnt,tmp;

int main()
{
    
    scanf("%d%lld",&n,&m);
    for (i = 1; i <= n; i++) scanf("%d",&a[i]);
    l = 1; r = 0; cnt = 0; pos = 1;
    for (i = 1; i <= n; i++)
    {
        cnt += a[i];
        while (cnt > m) cnt -= a[pos++];
        if (pos > i) 
        {
            printf("-1\n");
            exit(0);
        }
        while (l <= r && a[i] >= a[q[r]]) 
        {
            if (l < r) s.erase(a[q[r]] + f[q[r-1]]);
            r--;
        }
        q[++r] = i;
        if (l < r) s.insert(a[q[r]] + f[q[r-1]]);
        while (q[l] < pos)
        {
            if (l < r) s.erase(a[q[l+1]] + f[q[l]]);
            l++;
        }
        f[i] = f[pos-1] + a[q[l]];
        tmp = *s.begin();
        if (l < r && tmp < f[i]) f[i] = tmp;
    }
    printf("%lld\n",f[n]);
    
    return 0;
}

 

posted @ 2018-07-19 22:22  evenbao  阅读(126)  评论(0编辑  收藏  举报