• 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 数据库学习笔记03 存储过程
    Mysql 数据库学习笔记02 编程
    Mysql 数据库学习笔记01查询
    Struts2学习笔记04 之 拦截器
    Struts2学习笔记03 之 Result组件
    Group by与having理解
    Spring Assert断言工具类
    字符集、编码
    hibernate中Query的list和iterator区别(续)
    hibernate中Query的list和iterator区别
  • 原文地址:https://www.cnblogs.com/lienus/p/4292309.html
Copyright © 2020-2023  润新知