DP ---- LIS(シーケンスをアップ上昇)、およびLCS(最長共通部分列)の問題

LISの問題

https://www.acwing.com/problem/content/898/

アイデア:最初に、結果を維持するために、Fの配列を開く預金入力の数字の配列(元数)aは、最終的な長さは、Fの最終的な答えのアレイである。もし、今保存数Fアレイ、ときアレイ最初のiに位置は、最初の[CNT F> [I]を決定する際 ]!この数よりも大きいが、すなわち[CNT ++] F、配列Fに直接添加されている場合は[= i]は、 この操作中に見かけ。
[CNTは=ときに[I] <Fの数は、我々は、[i]は、全体のプロセスは、我々は、配列Fを維持することであるので、最初の配列は、[I]以上であるFで交換する必要がある場合インクリメンタルアレイは、我々はLOGN時間複雑な状況下で直接対応する位置を見つけるためにバイナリサーチを使用し、次に置き換えることができ、すなわち、F [L]は[I = ]は。

私たちは[i]がFを交換するために使用する意味[i]がある:[i]の最後厳密に単調増加するシーケンス番号で、シーケンス番号はリットルで、この数です。

あなたが最終的な結果を得ることができた後、私たちは完全な配列を通過するときようにします。

分析時間の複雑さ:O(nlogn)O(nlogn)
C ++コード

 

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
N INT、[100001]、DP [100001]、lenの; 
メインINT(){ 
    CIN >> N。
    以下のために(INT i = 1; iが= <N; iは++)CIN >> [I]。
    DP [1] [1]、LEN = 1 =。
    (I = 2 iがint型++; iが<= N)のために{ 
        (DP [LEN] <[i])とDP [++ LEN]は[I] =あれば、

        他{ 
            INT J = LOWER_BOUND(DP + 1、DP + LEN + 1、[I]) - DP; //真好下限用
            DP [j]が= [I]。

        } 
    } 
    COUT << lenを、
    0を返します。

LCSの問題

 簡単に言えば、コードを見て、何も言うことは理解することはできないはずです。

C ++コード

 

#include<bits/stdc++.h>
using namespace std;
string a,b;
int dp[2001][2001];
int main(){

    int len1,len2;
    cin>>len1>>len2>>a>>b;
    for(int j=1;j<=len2;j++)
    for(int i=1;i<=len1;i++){
    if(a[i-1]==b[j-1]) dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
    else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);//阶段划分:已经处理的前缀长度 
    }
    cout<<dp[len1][len2];
    return 0;
}

 

おすすめ

転載: www.cnblogs.com/myhnb/p/11305551.html