zoukankan      html  css  js  c++  java
  • PAT-1045. Favorite Color Stripe (30)-LIS

    将Eva喜欢的颜色按顺序编个优先级,

    2 3 1 5 6-> 1 2 3 4 5

    然后读取stripe,将Eva不喜欢的先剔除掉,剩下的颜色替换为相应的优先级

    2 2 4(去掉) 1 5 5 6 3 1 1 5 6 就变为:

    1 1 3 4 4 5 2 3 3 4 5

    接下来就是求最长上升子序列LIS的问题了,搞定~

    O(n^2)的算法:

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <algorithm>
    
    using namespace std;
    const int maxn=10000+5;
    int n,m;
    int level[205];
    int vis[205];
    int a[maxn];
    int main()
    {
        scanf("%d",&n);
        scanf("%d",&m);
        memset(vis,0,sizeof(vis));
        int tmp;
        for(int i=1;i<=m;i++){
            scanf("%d",&tmp);
            level[tmp]=i;
            vis[tmp]=1;
        }
        int cnt=0;
        int L;
        scanf("%d",&L);
        for(int i=0;i<L;i++){
            scanf("%d",&tmp);
            if(vis[tmp]){
                a[cnt++]=level[tmp];
            }
        }
        //LIS最长上升子序列O(N^2)算法
        int dp[maxn]; //dp[i]表示以a[i]结尾的最长上升子序列的长度
        memset(dp,0,sizeof(dp));
        int ans=0;
        for(int i=0;i<cnt;i++){
            dp[i]=1;
            for(int j=0;j<=i-1;j++){
                if(a[j]<=a[i] && dp[j]+1>dp[i]){
                    dp[i]=dp[j]+1;
                }
            }
            if(dp[i]>ans)
                ans=dp[i];
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    还想写一遍O(nlogn)的算法,但就是不知道为啥第三个样例一直WA,我觉得应该不是算法写错的问题。。。

    先把代码贴出来吧,如果有人看到知道错在哪了,还请赐教~~谢谢

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <algorithm>
    
    using namespace std;
    const int maxn=10000+5;
    int n,m;
    int level[205];
    int vis[205];
    int a[maxn];
    
    /*
    
    找出满足条件d[j-1]< val <= d[j]的j,最后结果返回l即为j的值
    
    为什么第三个样例WA????!!!!
    
    6
    0
    12 2 2 4 1 5 5 6 3 1 1 5 6
    
    */
    int Binary_Search(int l,int r,int val){
        int mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(val>a[mid])
                l=mid+1;
            else
                r=mid-1;
        }
        return l;
    }
    
    int main()
    {
        scanf("%d",&n);
        scanf("%d",&m);
        memset(vis,0,sizeof(vis));
        int tmp;
        for(int i=1;i<=m;i++){
            scanf("%d",&tmp);
            level[tmp]=i;
            vis[tmp]=1;
        }
        int cnt=0;
        int L;
        scanf("%d",&L);
        for(int i=0;i<L;i++){
            scanf("%d",&tmp);
            if(vis[tmp]){
                a[cnt++]=level[tmp];
            }
        }
        //如果Eva喜欢的颜色在stripe里面没有的话,那么输出是0!然而第三个样例还是WA。。。
        if(cnt==0){
            printf("0
    ");
        }
        else{
        //LIS最长上升子序列O(NlogN)算法
            int dp[maxn]; //dp[i]表示长度为i的最长上升子序列中最小的末尾元素
            dp[1]=a[0];
            int len=1;
            for(int i=1;i<cnt;i++){
                if(dp[len]<=a[i]){
                    len++;
                    dp[len]=a[i];
                }
                else{
                    int idx=lower_bound(dp+1,dp+len+1,a[i])-dp;
                    dp[idx]=a[i];
                }
            }
            printf("%d
    ",len);
        }
        return 0;
    }
    View Code

     关于lower_bound函数,是在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

    (注意:此时的last在原数组是越界的)

  • 相关阅读:
    JSP自定义标签
    Java集合之Arrays 剖析
    关于Java8中的Comparator那些事
    关于Comparable和Comparator那些事
    浅析Thread的join() 方法
    多线程的具体实现
    如何实现 List 集合的线程安全
    集合使用 Iterator 删除元素
    Tomcat目录详解
    一文读懂微服务架构
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/6677015.html
Copyright © 2011-2022 走看看