zoukankan      html  css  js  c++  java
  • POJ 2373 单调队列优化DP

    题意:
    这里写图片描述
    这里写图片描述
    思路:
    f[i] = min(f[j]) + 1; 2 * a <= i - j <= 2 *b;
    i表示当前在第i个点。f[i]表示当前最少的线段个数
    先是N^2的朴素DP(果断TLE)

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n,l,A,B,tot=1,xx,yy,f[1000050];
    struct Node{int x,y;}node[1050];
    bool cmp(Node a,Node b){if(a.x!=b.x)return a.x<b.x;return a.y<b.y;}
    int main()
    {
        memset(f,0x3f,sizeof(f));
        f[0]=0;
        scanf("%d%d%d%d",&n,&l,&A,&B);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&node[i].x,&node[i].y);
        }
        sort(node+1,node+1+n,cmp);
        for(int i=1;i<=l;i++){
            while(i>node[tot].x&&tot<n){i=node[tot].y;tot++;}
            if(i&1)continue;
            for(int j=2*A;j<=2*B;j+=2){
                f[i]=min(f[i],f[i-j]+1);
            }
        }
        printf("%d
    ",f[l]);
    }

    下面我们开始想优化…

    a和b都是常数,,他要找一个最大值。。
    1.线段树优化 (卡时过)
    2.单调队列优化
    注意插入的时候要等到算f[i+2*a]的时候再把f[i]插到队列里。

    (用STL的双端队列写得)

    //By SiriusRen
    #include <deque>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n,l,A,B,tot=1,xx,yy,f[1000050];
    struct Node{int x,y;}node[1050],jy;
    bool cmp(Node a,Node b){if(a.x!=b.x)return a.x<b.x;return a.y<b.y;}
    deque<Node>q;
    int main(){
        memset(f,0x3f,sizeof(f)),f[0]=0;
        scanf("%d%d%d%d",&n,&l,&A,&B);
        for(int i=1;i<=n;i++)scanf("%d%d",&node[i].x,&node[i].y);
        sort(node+1,node+1+n,cmp);
        for(int i=1;i<=n;i++)
            for(int j=max(node[i].x+1,node[i-1].y);j<node[i].y;j++)f[j]=0x5fffffff;
        for(int i=A*2;i<=l;i+=2){
            while(!q.empty()&&q.front().x<i-2*B)q.pop_front();
            while(!q.empty()&&q.back().y>f[i-2*A])q.pop_back();
            if(f[i-2*A]<0x3ffffff)
                jy.x=i-2*A,jy.y=f[i-2*A],q.push_back(jy);
            if(f[i]>=0x4fffffff)continue;
            if(!q.empty())f[i]=q.front().y+1;
        }
        if(f[l]<0x3ffffff)printf("%d
    ",f[l]);
        else puts("-1");
    }

    这里写图片描述

  • 相关阅读:
    剑指Offer 07 重建二叉树
    剑指Offer 06 从尾到头打印链表
    剑指Offer 05 替换空格
    剑指Offer 04 二维数组中的查找
    剑指Offer 03 数组中重复的数字
    leetcode518
    leetcode474
    leetcode376
    leetcode646
    leetcode213
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532295.html
Copyright © 2011-2022 走看看