zoukankan      html  css  js  c++  java
  • HDU 1423 最长公共字串+上升子序列

    http://acm.hdu.edu.cn/showproblem.php?pid=1423

    在前一道题的基础上多了一次筛选

    要选出一个最长的递增数列

    lower_bound()函数很好用,二分搜索找出满足ai>k的ai最小指针

    还有upper_bound()

    头文件#include<algorithm>

    比如求长度为n的数组a中k的个数:upper_bound(a,a+n,k)-lower_bound(a,a+n,k)

    int 放在main函数里面声明会出现程序崩溃,放在全局就没有问题,这里不知原因

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int i,j,n,m,h,a,b;
    int s[600],t[600],lable[600][600],dp[600][600];
    int ai[600],dpp[600];
    void mem()
    {
        memset(s,0,sizeof(s));
        memset(t,0,sizeof(s));
    
        memset(ai,0,sizeof(s));
        memset(dpp,0,sizeof(s));
        for(i=1;i<600;i++)
        {
            memset(dp[i],0,sizeof(s));
            memset(lable[i],0,sizeof(s));        
        }
    }
    int main()
    {
        int NN;
        scanf("%d",&NN);
        while(NN--)
        {
            mem();
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                scanf("%d",&s[i]);
            }
            scanf("%d",&m);
            for(i=0;i<m;i++)
            {
                scanf("%d",&t[i]);
            }
            for(i=0;i<n;i++)
            {
                for(j=0;j<m;j++)
                {
                    if(s[i]==t[j])
                    {
                        dp[i+1][j+1]=dp[i][j]+1;
                        lable[i+1][j+1]=1;
                    }
                    else
                    {
                        if(dp[i][j+1]>dp[i+1][j])
                        {
                            dp[i+1][j+1]=dp[i][j+1];
                            lable[i+1][j+1]=2;
                        }
                        else
                        {
                            dp[i+1][j+1]=dp[i+1][j];
                            lable[i+1][j+1]=3;
                        }
                    }
                }
            }
            a=n;b=m;
            h=dp[n][m];
            while(lable[a][b]!=0)
            {
                if(lable[a][b]==1)
                {
                    a--;b--;h--;
                    ai[h]=s[a];//or t[b]
                }
                else if(lable[a][b]==2)
                {
                    a--;
                }
                else if(lable[a][b]==3)
                {
                    b--;
                }
            }
            fill(dpp,dpp+n,INF);
            h=dp[n][m];
            for(i=0;i<h;i++)
            {
                *lower_bound(dpp,dpp+h,ai[i])=ai[i];
            }
            cout<<lower_bound(dpp,dpp+n,INF)-dpp<<endl;
            if(NN) cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    趣图:程序员告诉你为什么充钱后速度更快
    金三银四铜五铁六,面试得做好这个准备
    Java中如何模拟真正的同时并发请求?
    趣图:程序员最头疼的原因
    Java并发面试题
    linux内存分配与回收
    7.3 Set集合
    7.2 Java 11新增的Collection和Iterator接口
    7.1 Java集合概念
    6.5 正则表达式
  • 原文地址:https://www.cnblogs.com/dzzy/p/5283305.html
Copyright © 2011-2022 走看看