复习【dp+单调队列】


处理10W数据:二分答案+单调队列+dp

这题可以用二维Dp和一维Dp来做,虽然两者时间复杂度都是O(N2),但二维的无法被优化,一维的可以用单调队列将时间效率缩为O(N)。
因此构造Dp时优先采用纬度小的方案。

单调队列的核心模板见代码。

ps:在一部分单调队列的题目中,队列各项的数值会同时变化。此时应用变量Plus做维护


#include <iostream>
using namespace std;

struct qnode
{
    long tim, x;
};
const long N=100010;
long n, T, hea, tai;
long a[N], d[N];
qnode b[N];

void add(long x, long y)                        //压入操作
{
    while (tai >= hea && b[tai].x >= x)
        tai--;
    tai++;
    b[tai].x=x; b[tai].tim=y;
}

long draw(long y)                                //取出操作
{
    while (b[hea].tim < y)
        hea++;
    return b[hea].x;
}

bool check(long m)
{
    long i;
    hea=1; tai=0;
    add(0, 0);
    for (i=1; i<=n+1; i++)
    {
        a[i]=d[i]+draw(i-m-1);
        add(a[i], i);
    }
    return (a[n+1] <= T);
}

long work()
{
    long l=0, r=n, mid;    
    if (check(0)) return 0;
    while (l+1 < r)
    {
        mid=(l+r)/2;
        if (check(mid)) r=mid;
        else l=mid;

    }
    return r;
}

int main()
{
    long i;
    freopen("revision.in", "r", stdin);
    freopen("revision.out", "w", stdout);
    scanf("%ld%ld", &n, &T);
    for (i=1; i<=n; i++)
        scanf("%ld", &d[i]);
    printf("%ld\n", work());
    return 0;
}

 

posted @ 2016-08-14 17:28  tswddd  阅读(147)  评论(0)    收藏  举报