TOJ 3601.Longest Contiguous Subsequence 最長連續公共子序列

最長連續公共子序列問題

最長連續公共子序列,和公共子序列不一樣。這裏要求子序列連續,相對而言要簡單一些。


算法設計思路是動態規劃(雖然我感覺和動態規劃的感覺不怎麼相對)。假設兩個序列s1[m]和s2[n],循環遍歷s1和s2,當出現 s1[i] == s2[j] 的時候,這一對(i,j)就是公共序列的一部分,如果(i == 0 || j == 0)則(i,j)就是這個公共序列的開始,否則,則可能是一個公共序列的中間部分或者也可能是開始。用一個二維矩陣s[m][n]來標記,s[m][n]表示s1[i]和s2[j]之間的對應關係。
如果s1[i] != s2[j],則 s[i][j] == s[i - 1][j - 1] + 1
若s[i][j] == 0,則表明s1[i] != s2[j],若 s[i][j] == 1,則表明(i,j)是一個公共序列的開始部分,若s[i][j] > 1,表明(i,j)是公共序列的中間部分。

程序代碼

#include <stdio.h>

int main(){
    int m,n;
    scanf("%d %d",&m,&n);
    const int p = m;
    const int q = n;
    int s1[p];
    int s2[q];
    for(int i = 0;i < m;i ++)
        scanf("%d",s1 + i);
    for(int i = 0;i < n;i ++)
        scanf("%d",s2 + i);
    int s[p][q];
    int max = 0;
    for(int i = 0;i < m;i ++)
        for(int j = 0;j < n;j ++)
            s[i][j] = 0;
    for(int i = 0;i < m;i ++){
        for(int j = 0;j < n;j ++){
            if(s1[i] == s2[j]){
                if(i == 0||j == 0)
                    s[i][j] = 1;
                else{
                    s[i][j] = s[i - 1][j - 1] + 1;
                    if(s[i][j] > max)
                        max = s[i][j];
                }
            }
        }
    }
    printf("%d\n",max);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章