码迷,mamicode.com
首页 > 其他好文 > 详细

复习【dp+单调队列】

时间:2016-08-14 18:59:40      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:

技术分享


处理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;
}

 

复习【dp+单调队列】

标签:

原文地址:http://www.cnblogs.com/tswddd/p/5770586.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!