[题目链接]
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 "); 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 ",f[n]); return 0; }