您的位置:首页 > 产品设计 > UI/UE

poj 3245 Sequence Partitioning(dp+二分+单调队列+sbt)

2012-09-15 19:24 579 查看
Sequence Partitioning

Time Limit: 8000MSMemory Limit: 65536K
Total Submissions: 710Accepted: 207
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 =ri − 1 + 1, li ≤ ri, 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}, 1 ≤ i ≤ p
it is provided that



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:1 ≤ i ≤ p}
Could you tell me the minimum?

Input

The input contains exactly one test case. The first line of input contains two positive integers N (N ≤ 50000), Limit (Limit ≤ 231-1). 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
题目:http://poj.org/problem?id=3245

题意:给你一个数列对,其实就是两个数列,你可以把数列分成任意段,要求如下:

1.对于任意元素p和元素q(p<q)在不同段中,那么有Bp>Aq

2.所有段的A元素的最大值的和要小于给定的限制

求满足上面条件下,每个段B元素的和 的最大值

分析:首先考虑第一个限制,我们会发现,只有有数列后面的aj大于等于当前的bi,那么i到j的所有元素必须在一个块,那么就把他们合并,合并就是a取最大值,b取和,具体怎么合并有很多方法,我们可以将b元素的下标,按b从小到大排序,然后反向枚举a元素,标记所有小于a元素的b元素都标记上最大的标号,然后扫描一遍合并所有块

剩下的就是第二个限制了,我们会发现,第二个限制就是这题的反向求解,我们只要二分答案,用之前那题的做法判断可行性就行了

代码:

#include<set>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int mm=55555;
int a[mm],q[mm],p[mm],f[mm],b[mm];
int i,j,n,limit,l,r,m,ans;
multiset<int>sbt;
bool check(int s)
{
    int i,p,l=0,r=-1,tmp;
    __int64 sum=0;
    sbt.clear();
    for(p=i=1;i<=n;++i)
    {
        sum+=b[i];
        while(sum>s)sum-=b[p++];
        if(p>i)return 0;
        while(l<=r&&a[i]>=a[q[r]])
        {
            if(l<r)sbt.erase(f[q[r-1]]+a[q[r]]);
            --r;
        }
        q[++r]=i;
        if(l<r)sbt.insert(f[q[r-1]]+a[q[r]]);
        while(q[l]<p)
        {
            if(l<r)sbt.erase(f[q[l]]+a[q[l+1]]);
            ++l;
        }
        f[i]=f[p-1]+a[q[l]];
        tmp=*sbt.begin();
        if(l<r&&f[i]>tmp)f[i]=tmp;
    }
    return f
<=limit;
}
bool cmp(int u,int v)
{
    return b[u]<b[v];
}
int main()
{
    while(~scanf("%d%d",&n,&limit))
    {
        for(i=1;i<=n;++i)
            scanf("%d%d",&a[i],&b[i]),q[i]=p[i]=i;
        sort(p+1,p+n+1,cmp);
        for(j=1,i=n;i>0;--i)
            while(j<=n&&b[p[j]]<=a[i])q[p[j++]]=i;
        for(j=i=1;i<=n;i=l,++j)
        {
            a[j]=a[i],b[j]=b[i];
            for(l=i+1,r=max(q[i],i);l<=r;++l)
            {
                b[j]+=b[l];
                a[j]=max(a[j],a[l]);
                if(q[l]>r)r=q[l];
            }
        }
        n=j-1,l=0,r=2147483647;
        while(l<=r)
        {
            m=(l+r)>>1;
            if(check(m))ans=m,r=m-1;
            else l=m+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: