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");
    }

    这里写图片描述

  • 相关阅读:
    巴洛克式和哥特式的区别
    推荐阅读书籍,是时候再行动起来了。
    AtCoder ABC 159F Knapsack for All Segments
    AtCoder ABC 159E Dividing Chocolate
    AtCoder ABC 158F Removing Robots
    AtCoder ABC 158E Divisible Substring
    AtCoder ABC 157F Yakiniku Optimization Problem
    AtCoder ABC 157E Simple String Queries
    AtCoder ABC 157D Friend Suggestions
    AtCoder ABC 156F Modularness
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532295.html
Copyright © 2011-2022 走看看