POJ 3245|Sequence Partitioning|动态规划|单调队列

来源:互联网 发布:星云数据服务平台 编辑:程序博客网 时间:2024/05/17 06:42

题意真是难懂。。

题意

一个长度为N的序列(每个元素是(ai,bi)这样的数对),连续地分成若干组。每组左右边界是(l1,r1),(l2,r2),,(lp,rp),满足li=ri1+1,liri,l1=1,rp=n。分组必须满足两个条件:前面组的元素的b值比后面组元素的a值大;令Mi为第i个组内最大的a,所有Mi的和不超过limit。令Si为第i个组的元素的b的和,最小化max{Si}

题解

二分答案。
能否破除ba的关系呢?
考虑什么情况下必须捆绑在一起。
如果ai>bj,那么任意bkbj,都必须与ai捆绑在一起,否则不符合题意。
所以考虑排序bj,然后从大到小扫。
然后剩下的就没有限制了,于是问题就变成,给出一个数列,(每个组a的最大值)的和不能超过limit,(各组内b的的和)的最大值最小。
那么和POJ 3017很类似了?
一个单调队列优化DP
不过POJ 3017必须要set维护,本题就无所谓了。。

代码

#include <cstdio>#include <algorithm>using namespace std;const int N = 50005, inf = 0x7fffffff;int n, limit, q[N], a[N], b[N], dp[N], p1[N], p2[N];bool check(int m) {    int i, j = 1, k, s = 0, f = 0, r = 0;    for (i = 1; i <= n; ++i) {        s += b[i];        while (s > m) s -= b[j++];        if (j > i) return 0;        while (f < r && a[q[r - 1]] <= a[i]) --r;        while (f < r && q[f] < j) ++f;        q[r++] = i;        dp[i] = dp[j - 1] + a[q[f]];        for (k = f + 1; k < r; ++k)            dp[i] = min(dp[i], dp[q[k - 1]] + a[q[k]]);    }    return dp[n] <= limit;}bool cmp(int x, int y) {    return b[x] < b[y];}int main() {    int i, j, l, r, mid;    while (scanf("%d%d", &n, &limit) == 2) {        for (i = 1; i <= n; ++i)            scanf("%d%d", &a[i], &b[i]), p1[i] = p2[i] = i;        sort(p1 + 1, p1 + n + 1, cmp);        for (j = 1, i = n; i >= 1; --i)            for (; j <= n && b[p1[j]] <= a[i]; ++j)                p2[p1[j]] = i;        for (i = 1, j = 1; i <= n; i = l, ++j) {            a[j] = a[i]; b[j] = b[i];            for (l = i + 1, r = max(p2[i], i); l <= r; ++l) {                a[j] = max(a[j], a[l]);                b[j] += b[l];                r = max(r, p2[l]);            }        }        n = j - 1;        for (l = 0, r = inf; l < r) {            mid = l + r >> 1;            if (check(mid)) r = mid;            else l = mid + 1;        }        printf("%d\n", l);    }    return 0;}

Sequence Partitioning

Time Limit: 8000MS Memory Limit: 65536K
Total Submissions: 1286 Accepted: 346
Case Time Limit: 5000MS

Description

Given a sequence of N ordered pairs of positive integers (Ai,Bi), you have to partition it into several contiguous parts. Let p be the number of these parts, whose boundaries are (l1,r1),(l2,r2),...,(lp,rp), which satisfy li=ri1+1,liri,l1=1,rp=n. The parts themselves also satisfy the following restrictions:

For any two pairs (Ap,Bp),(Aq,Bq), where (Ap,Bp) is belongs to the Tpth part and (Aq,Bq) the Tqth part. If Tp<Tq, then Bp>Aq.

Let Mi be the maximum A-component of elements in the ith part, say

Mi=max{Ali,Ali+1,,Ari},1ip

it is provided that

i=1pMiLimit

where Limit is a given integer.

Let Si be the sum of B-components of elements in the ith part. Now I want to minimize the value

max{Si:1ip}

Could you tell me the minimum?

Input

The input contains exactly one test case. The first line of input contains two positive integers N(N50000),Limit(Limit2311). Then follow N lines each contains a positive integers pair (A, B). It’s always guaranteed that

max{A1,A2,,An}Limit

Output

Output the minimum target value.

Sample Input

4 64 33 52 52 4

Sample Output

9

Hint

An available assignment is the first two pairs are assigned into the first part and the last two pairs are assigned into the second part. Then B1>A3,B1>A4,B2>A3,B2>A4,max{A1,A2}+max{A3,A4}6, and minimum max{B1+B2,B3+B4}=9.

Source

POJ Monthly–2007.07.08, Chen, Danqi

0 0