• [2020.12.3周四]最长上升子序列


    [2020.12.3周四]最长上升子序列LIS

    hdu5256序列变换

    题意:给定一个序列a[],问至少需要修改多少个数,才能使a[]严格递增。

    题解:ans=n-LIS

    算法:这个算法dp写需要O(n^2),dp到每个数的最长上升子序列长度,(dp[i]=max_{j<i,a[j]<a[i]}(dp[j]))

    ​ 有点偏序的意思,其实可以写离散后写树状数组二维偏序的,但太麻烦了。

    ​ 其实可以这样dp(如下程序),dp[i]=长度为i+1的序列的尾部最小数

    ​ 如果当前数比dp所有数大,就把他加入dp数组

    ​ 否则,它必然可以把一个dp长度尾部的数替换掉;

    tag:最长上升子序列

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    const int inf =0x3f3f3f3f;
    int a[maxn];
    int main()
    {
        int T;scanf("%d",&T);int t=0;
        while(T--)
        {
            int n;scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%d",a+i),a[i]-=i;//把严格递增转成非严格递增
            vector<int>dp;
            for(int i=1;i<=n;i++)
            {
                auto pos=upper_bound(dp.begin(),dp.end(),a[i]);
                if(pos==dp.end()) dp.push_back(a[i]);
                else *pos=a[i];
            }
            printf("Case #%d:
    ",++t);
            printf("%d
    ",n-(int)dp.size());
        }
    }
    
    

    E - Make It Increasing

    题意:给定一个序列a[],问至少需要修改多少个数,才能使a[]严格递增,其中有k个数是不可以修改的。

    题解:遇上题同理,区别在于k个不能修改的数,将a[] 分成k+1段,分段求LIS

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=5e5+100; 
    const int inf=0x3f3f3f3f;
    ll a[maxn],b[maxn];
    int main()
    {
        int n,k;
        cin>>n>>k;bool flag=true;
        for(int i=1;i<=n;i++)cin>>a[i],a[i]-=i;//a[i]>=0,非严格递增
        for(int i=1;i<=k;i++) cin>>b[i]; 
        b[0]=0;b[k+1]=n+1;a[0]=-1e9-2;a[n+1]=1e9+10;
        int  ans=0;
        for(int i=0;i<=k;i++)
        {
            int l=b[i],r=b[i+1];
            if(a[l]>a[r]) {
                cout<<"-1"<<endl;return 0;
            }
            vector<int>dp;
            for(int j=l+1;j<r;j++)//求一段a[],值在[a[l],a[r]]内的最长子序列
            {
                if(a[l]<=a[j]&&a[j]<=a[r]) 
                {
                    auto pos=upper_bound(dp.begin(),dp.end(),a[j]);
                    if(pos==dp.end())dp.push_back(a[j]);
                    else *pos=a[j];
                }
            }
            ans+=(r-l-1)-(int)dp.size(); 
        }
        cout<<ans<<endl;
    }
    

    洛谷P2782

    题意:洛谷模板题。给南北两岸友好城市的坐标,问最多有多少对城市两两不相交。

    题解:排序一边城市,另一边城市求一个LIS。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e5+100;
    const int inf =0x3f3f3f3f;
    pair<int,int> a[maxn];
    int s[maxn];
    int main()
    {
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&a[i].first,&a[i].second);
        sort(a+1,a+1+n);
        vector<int>dp;
        for(int i=1;i<=n;i++)
        {
            auto pos=upper_bound(dp.begin(),dp.end(),a[i].second);
            if(pos==dp.end())dp.push_back(a[i].second);
            else *pos=a[i].second;
        }
        printf("%d",(int)dp.size());
    }
    
    

    拓展

    (1)LIS的期望

  • 相关阅读:
    搭建SpringCloud之注册中心Eureka
    学习角色管理模块错误总结---基于SpringMVC框架
    【转】Eclipse 单步调试
    [转]MyBatis的foreach语句详解
    解决pom.xml文件 ---- web.xml is missing and <failOnMissingWebXml> is set to true
    解决Dynamic Web Module 3.0 Requires Java 1.6 or newer
    用maven在eclipse用spring建javaweb工程(一)
    【转载】Eclipse 断点调试
    学习大神笔记之“MyBatis学习总结(三)”
    学习大神笔记之“MyBatis学习总结(二)”
  • 原文地址:https://www.cnblogs.com/zx0710/p/14083757.html
Copyright © 2020-2023  润新知