首页 > 其他 > 详细

复习【dp+单调队列】

时间:2016-08-14 18:59:30      阅读:134      评论: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
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!