zoukankan      html  css  js  c++  java
  • hdu4521(线段树+dp)

    传送门:小明系列问题——小明序列

    题意:有n个数,求间距大于d的最长上升序列。

    分析:dp[i]表示在i点以a[i]结束距离大于d的最长上升序列,然后每更新到第i点时,取i-d之前小于a[i]的数为结束的最长上升序列进行状态转移,并维护前i-d之前的最大上升序列,维护i-d之前的每点为结束的最长上升序列用线段树维护即可。

    #pragma comment(linker,"/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <limits.h>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 100000000
    #define inf 0x3f3f3f3f
    #define eps 1e-6
    #define N 100010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define PII pair<int,int>
    using namespace std;
    inline int read()
    {
        char ch=getchar();
        int x=0;
        while(ch>'9'||ch<'0')ch=getchar();
        while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
        return x;
    }
    int dp[N],a[N];
    int mx[N<<2];
    void pushup(int rt)
    {
        int ls=rt<<1,rs=ls|1;
        mx[rt]=max(mx[ls],mx[rs]);
    }
    void build(int l,int r,int rt)
    {
        mx[rt]=0;
        if(l==r)return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void update(int pos,int c,int l,int r,int rt)
    {
        if(l==r)
        {
            mx[rt]=max(mx[rt],c);
            return;
        }
        int m=(l+r)>>1;
        if(pos<=m)update(pos,c,lson);
        else update(pos,c,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
            return mx[rt];
        int m=(l+r)>>1;
        int res=0;
        if(L<=m)res=max(res,query(L,R,lson));
        if(m<R)res=max(res,query(L,R,rson));
        return res;
    }
    int main()
    {
        int n,d;
        while(scanf("%d%d",&n,&d)>0)
        {
            build(0,N,1);
            for(int i=1;i<=n;i++)dp[i]=1;
            int ans=1;
            for(int i=1;i<=n&&i<=d;i++)
            {
                //scanf("%d",&a[i]);
                a[i]=read();
            }
            for(int i=d+1;i<=n;i++)
            {
                //scanf("%d",&a[i]);
                a[i]=read();
                if(a[i]>0)dp[i]=query(0,a[i]-1,0,N,1)+1;
                else dp[i]=1;
                update(a[i-d],dp[i-d],0,N,1);
                ans=max(ans,dp[i]);
            }
            printf("%d
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    mysql修改数据表名
    HDU 5742 It's All In The Mind (贪心)
    HDU 5752 Sqrt Bo (数论)
    HDU 5753 Permutation Bo (推导 or 打表找规律)
    HDU 5762 Teacher Bo (暴力)
    HDU 5754 Life Winner Bo (博弈)
    CodeForces 455C Civilization (并查集+树的直径)
    CodeForces 455B A Lot of Games (博弈论)
    CodeForces 455A Boredom (DP)
    HDU 4861 Couple doubi (数论 or 打表找规律)
  • 原文地址:https://www.cnblogs.com/lienus/p/4292309.html
Copyright © 2011-2022 走看看