POJ 3017|Cut the Sequence|动态规划|单调队列

来源:互联网 发布:淘宝领券口令怎么用 编辑:程序博客网 时间:2024/05/23 21:47

给定一个数列{an},任意将连续的ai分块,使所有块的和都不超过M,最小化各块的最大值的和。

dp[i]=min{dp[j]+max{a[j..i1]}}

其中i1k=jakM
时间复杂度是O(n2),通过打表我们可以发现决策单调性(误),由于dp[i]是单调增的,ak的最大值也是单调不降的,而且还得满足和不大于M,因此j是不减的,考虑单调队列。
开一个单调队列,使得队首到当前位置的和不超过m,那么单调队列里随便哪个元素都是满足要求的:
dp[i]=min{dp[q[j]]+a[q[j+1]]}

对于单调队列的最小值,set维护即可。

#include <cstdio>#include <set>using namespace std;typedef long long ll;const int N = 100005;int q[N], dp[N], a[N];multiset<int> s;ll calc(int n, ll m) {    int i, j = 1, k, f = 0, r = 0; ll sum = 0;    for (i = 1; i <= n; ++i) {        sum += a[i];        while (sum > m) sum -= a[j++];        if (j > i) return -1;        while (f < r && a[q[r - 1]] <= a[i]) {            if (r - f >= 2) s.erase(dp[q[r - 2]] + a[q[r - 1]]);            --r;        }        q[r++] = i; if (r - f >= 2) s.insert(dp[q[r - 2]] + a[q[r - 1]]);        while (f < r && q[f] < j) {            if (r - f >= 2) s.erase(dp[q[f]] + a[q[f + 1]]);            ++f;        }        dp[i] = dp[j - 1] + a[q[f]];        if (r - f >= 2) dp[i] = min(dp[i], *s.begin());    }    return dp[n];}int main() {    int i, n; ll m;    scanf("%d%lld", &n, &m);    for (i = 1; i <= n; ++i) scanf("%d", &a[i]);    return printf("%lld", calc(n, m)), 0;}

Cut the Sequence

Time Limit: 2000MS Memory Limit: 131072K
Total Submissions: 9998 Accepted: 2999

Description

Given an integer sequence { an } of length N, you are to cut the sequence into several parts every one of which is a consecutive subsequence of the original sequence. Every part must satisfy that the sum of the integers in the part is not greater than a given integer M. You are to find a cutting that minimizes the sum of the maximum integer of each part.

Input

The first line of input contains two integer N (0 < N ≤ 100 000), M. The following line contains N integers describes the integer sequence. Every integer in the sequence is between 0 and 1 000 000 inclusively.

Output

Output one integer which is the minimum sum of the maximum integer of each part. If no such cuttings exist, output −1.

Sample Input

8 17
2 2 2 8 1 8 2 1

Sample Output

12

Hint

Use 64-bit integer type to hold M.

Source

POJ Monthly–2006.09.29, zhucheng

0 0