zoukankan      html  css  js  c++  java
  • LCS(记录路径)+LIS+LCIS

    https://blog.csdn.net/someone_and_anyone/article/details/81044153

    当串1 和 串2 的位置i和位置j匹配成功时,

    dp[i][j]=dp[i-1][j-1]+1,也就是说此状态由状态dp[i-1][j-1]转移而来,用数组记录为1,

    当匹配不成功时,dp[i-1][j]和dp[i][j-1]去一个最大的,用数组分别记为2和3.

    根据记录数组寻找路径:

    当记录数组为1时,说明次时的i和j想等,并且此状态由i-1和j-1转移而来,所以i=i-1,j=j-1

    当记录数组为2时,说明此时i和j对应的数符不等,并且此状态由j-1转移而来,所以直接j--;

    当记录数组为2时,说明此时i和j对应的数符不等,并且此状态由i-1转移而来,所以直接i--;

    例题:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1000+7;
    int dp[N][N];
    int mark[N][N];
    char s1[N],s2[N];
    int main()
    {
        cin>>s1+1>>s2+1;
        int n=strlen(s1+1);
        int m=strlen(s2+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(s1[i]==s2[j]){
                    dp[i][j]=dp[i-1][j-1]+1;
                    mark[i][j]=1;
                }
                else if(dp[i][j-1]>dp[i-1][j]){
                    dp[i][j]=dp[i][j-1];
                    mark[i][j]=2;    
                }
                else {
                    dp[i][j]=dp[i-1][j];
                    mark[i][j]=3;
                }
             }
        string ans="";
        int i=m,j=n;
        while(i>0&&j>0){
            if(mark[i][j]==1) {
                ans+=s1[i];
                i--;j--;
            }
            else if(mark[i][j]==2) {
                j--;
            }
            else i--;
        }
        reverse(ans.begin(),ans.end());
        cout<<ans<<endl;
        
        return 0;
    }

     LIS:最长上升子序列。

    O(n^2):

      定义dp[i]表示考虑到第i个元素,他可以拼接到从1~i-1中比它小的元素上去。

      dp[i]=max(dp[k])+1,代码比较简单,在此省略。

    O(nlogn):

      定义dp[len]表示当长度为len时的最小元素。

    code:

      

    dp[1]=a[1];
    int len=1;
    for(int i=1;i<=n;i++){
        if(a[i]>dp[len]) dp[++len]=a[i];
        else *lower_bound(dp+1,dp+1+len,a[i])=a[i];
    }

    LCIS:最长公共上升子序列

    定义状态dp[i][j]表示考虑前i个字符时,当选中第j个字符时的状态。

    在这里第j个字符已经选了,所以前i个字符一定有和它匹配的,当第j个字符和第i个字符不匹配成功时,那第j个字符一定和

    前i-1中的一个字符匹配喽,所以转移方程为dp[i][j]=dp[i-1][j],还是以j结尾。

    当第j个字符和第i个字符匹配成功时,dp[i][j]=max(dp[i-1][k])+1,要在和前i-1个匹配的字符中选出状态最好的。

    所以状态转移方程为:

    dp[i][j]=dp[i-1][j],匹配成功。

    dp[i][j]=max(dp[i-1][k])(k<=j)匹配不成功。

    code:

    void solve(int t){
        ll n,m; 
        cin >> n;
        for (ll i = 1; i <= n; i++) cin >> arr[i];;
        cin >> m;
        for (ll i = 1; i <= m; i++) cin >> brr[i];
        ll mx = 0;
        for (ll i = 1; i <= n; i++) {
            mx = 0;
            for (ll j = 1; j <= m; j++) {
                dp[i][j] = dp[i - 1][j];
                if (brr[j] < arr[i]) mx = max(mx, dp[i-1][j]);
                else if (arr[i] == brr[j]) dp[i][j] = mx + 1;
            }
        }
        ll ans = 0;
        for (ll i = 1; i <= m; i++)  ans = max(ans, dp[n][i]);
        cout << ans<<"
    "<<"
    "; 
    }

    一个例题:

    HDU1423:Greatest Common Increasing Subsequence

    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const ll N = 1E3 + 7;
    ll arr[N];
    ll brr[N];
    ll dp[N][N];
    void solve(int t){
        ll n,m; 
        cin >> n;
        for (ll i = 1; i <= n; i++) cin >> arr[i];;
        cin >> m;
        for (ll i = 1; i <= m; i++) cin >> brr[i];
        ll mx = 0;
        for (ll i = 1; i <= n; i++) {
            mx = 0;
            for (ll j = 1; j <= m; j++) {
                dp[i][j] = dp[i - 1][j];
                if (brr[j] < arr[i]) mx = max(mx, dp[i-1][j]);
                else if (arr[i] == brr[j]) dp[i][j] = mx + 1;
            }
        }
        ll ans = 0;
        for (ll i = 1; i <= m; i++)  ans = max(ans, dp[n][i]);
        cout << ans<<"
    ";
        if(t) cout<<"
    "; 
    }
    int main(){
        ll t;
        cin >> t;
        while (t--) solve(t);
        return 0;
    }
  • 相关阅读:
    java_爬虫_从腾讯视频播放界面爬取视频真实地址
    杂_小技巧_将网页上的内容通过亚马逊邮箱传到kindle中
    java_基础_接口和抽象类
    知乎上的50道SQL练习题
    第 4 章 WebDriver API
    第 2 章 测试环境搭建
    第 1 章 自动化测试基础
    【软件测试】9.QC管理学习(类禅道)学习
    01 Python简介、环境安装、变量、数据类型
    【MySQL面试指南】
  • 原文地址:https://www.cnblogs.com/Accepting/p/12457402.html
Copyright © 2011-2022 走看看