nyist oj 36 最長公用子序列 (動態規劃基礎題),nyistoj

來源:互聯網
上載者:User

nyist oj 36 最長公用子序列 (動態規劃基礎題),nyistoj
最長公用子序列時間限制:3000 ms  |  記憶體限制:65535 KB難度:3

描述
咱們就不拐彎抹角了,如題,需要你做的就是寫一個程式,得出最長公用子序列。
tip:最長公用子序列也稱作最長公用子串(不要求連續),英文縮寫為LCS(Longest Common Subsequence)。其定義是,一個序列 S ,如果分別是兩個或多個已知序列的子序列,且是所有符合此條件序列中最長的,則 S 稱為已知序列的最長公用子序列。
輸入
第一行給出一個整數N(0<N<100)表示待測資料群組數
接下來每組資料兩行,分別為待測的兩組字串。每個字串長度不大於1000.
輸出
每組測試資料輸出一個整數,表示最長公用子序列長度。每組結果佔一行。
範例輸入
2asdfadfsd123abcabc123abc
範例輸出
36
來源
經典
上傳者

hzyqazasdf

開始要刷動態規劃的題啦;從入門題練練手,http://blog.csdn.net/v_july_v/article/details/6695482 (關於演算法的講解)參考了大神的部落格,看了對這個內容有了那麼一點點瞭解了吧,直接用這個題目練練手。主要要掌握動態規劃的這種思想!

動態規劃思想,主要是遞推公式,求最佳化問題,保證當時位置是最優,分治的思想;

這個題目的思路就是,從最後一個字元開始,如果兩個字串的最後一個字元相等,說明最後一個字元,在最長的公用序列裡面,最長公用序列的前一個,肯定也是兩個字串的最長公用子序列,遞推公式就是 dp[i][j]=dp[i-1][j-1]+1;

其他情況,如果不相等就是 dp[i][j] = max(dp[i][j-1], dp[i-1][j]);

第一次水過的代碼;

#include <cstdio>#include <cstring>#define max(a, b) a > b ? a : busing namespace std;const int maxn=1001;int dp[maxn][maxn];//儲存當前位置最長公用子序列的個數char s1[maxn],s2[maxn];int main(){    int n;    int len1,len2;    scanf("%d",&n);    getchar();    while(n--)    {        memset(dp,0,sizeof(dp));        scanf("%s%s",s1,s2);        len1=strlen(s1);        len2=strlen(s2);        for(int i=1;i<=len1;i++)            for(int j=1;j<=len2;j++)        {            if(s1[i-1]==s2[j-1])//先前這個地方寫成s1[i]==s2[j]就一直wa 不知道為什麼,範例都能過                dp[i][j]=dp[i-1][j-1]+1;            else                dp[i][j] = max(dp[i][j-1], dp[i-1][j]);        }        printf("%d\n",dp[len1][len2]);    }    return 0;}

看到別人可以直接用一維數組來做,進行了記憶體上的最佳化;值得學習一下;

 #include <stdio.h>#include <string.h>char s1[1001], s2[1001];int dp[1001], t, old, tmp;int main(){    scanf("%d", &t);    getchar();    while(t--){        gets(s1);        gets(s2);        memset(dp, 0, sizeof(dp));        int lenS1=strlen(s1), lenS2=strlen(s2);        for(int i=0; i<lenS1; i++){            old=0;            //若s1[i]==s2[j], dp[i][j] = dp[i-1][j-1]+1            //否則,dp[i][j] = max(dp[i-1][j], dp[i][j-1])            //此處進行了空間最佳化,old 代表 dp[i-1][j-1]            //dp[j-1] 代表 dp[i][j-1], dp[j] 代表 dp[i-1][j]            for(int j=0; j<lenS2; j++){                tmp = dp[j];                if(s1[i]==s2[j])                    dp[j] = old+1;                else                    if(dp[j-1]>dp[j])dp[j]=dp[j-1];                old = tmp;            }        }        printf("%d\n", dp[lenS2-1]);    }    return 0;}        


找出(A,D,C,B,B,C,B)與(D,D,C,B,A,C)最長公用子序列,並給出構造過程

動態規劃
if(a[i]==b[j])
d[i][j]=d[i-1][j-1]+1
else
d[i][j]=max(d[i-1][j],d[i][j-1])
初始化
d[i][0]=0;
d[0][j]=0;
為節省空間的,可以用滾動數組 d只設定兩行就可以
 
動態規劃的問題:最長公用子序列代碼如下,為何當輸入兩個字串分別為“123456”以及“as”時輸出

main()前面不該有int,其次for迴圈裡如果迴圈變數是從0下表開始的,就該是小於strlen1和小於strlen2,沒有等於
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.