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

题意真是难懂。。

题意

一个长度为 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}

题解

二分答案。
能否破除 b a的关系呢?
考虑什么情况下必须捆绑在一起。
如果 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 Tp th part and (Aq,Bq) the Tq th part. If Tp<Tq , then Bp>Aq .

Let Mi be the maximum A-component of elements in the i th 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 6
4 3
3 5
2 5
2 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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值