hdu 1159, LCS, dynamic programming, recursive backtrack vs iterative backtrack vs incremental, C++

来源:互联网 发布:网络话飞机场什么意思 编辑:程序博客网 时间:2024/04/27 22:18

thanks prof. Abhiram Ranade for his vedio on Longest Common Subsequence ‘s back track search view in lecture 19, nice explanation indeed.

// back track, recursive, 390 ms, O(m*n) memory

#include <cstdio>#include <vector>#include <string>#include <iostream>#include <algorithm>#define MAXSIZE 1001using std::string;char *p1, *p2;int M, N;int table[MAXSIZE][MAXSIZE];int solveLCSlength(int i, int j) {    if(table[i][j]>=0) return table[i][j];    int k;    for(k=j;k<N && p2[k]!=p1[i];++k) {}    if(k!=N) table[i][j]=std::max(solveLCSlength(i+1,j),1+solveLCSlength(i+1,k+1));    else table[i][j]=solveLCSlength(i+1,j);    return table[i][j];}int LCSlength(string &s1, string &s2) {    p1=&s1[0], p2=&s2[0], M=s1.size(), N=s2.size();    for(int i=0;i<M;++i) {    for(int j=0;j<N;++j) { table[i][j]=-1; }        table[i][N]=0;    }    for(int j=0;j<=N;++j) { table[M][j]=0; }    return solveLCSlength(0,0);}int main() {    string s1, s2;    while(std::cin >> s1 >> s2) {        printf("%d\n",LCSlength(s1,s2));    }    return 0;}

// turn recursive backtrack version to iterative and reduce memory cost to O(m+n) , 312ms

#include <cstdio>#include <cstring>#include <algorithm>#define MAXSIZE 1001int LCSlength(char *s1, char *s2) {    static int table[MAXSIZE<<1];    int len1,len2, i,j,k, *prev,*curr;    len1=strlen(s1), len2=strlen(s2);    prev=&table[0], curr=&table[len2+1];    for(i=0;i<=len2;++i) prev[i]=0;    curr[len2]=0;    for(i=len1-1;i>=0;--i) {            char tmp=s1[i];        for(j=len2-1;j>=0;--j) {            for(k=j;k<len2 && tmp!=s2[k];++k) {}            curr[j]=prev[j];            if(k!=len2 && curr[j]==prev[k+1]) ++curr[j];        }        std::swap(prev,curr);    }    return prev[0];}int main() {    char s1[MAXSIZE], s2[MAXSIZE];    while(scanf("%s%s",s1,s2)==2) {        printf("%d\n",LCSlength(s1,s2));    }    return 0;}

// incremental, 31ms, O(m+n) memory

#include <cstdio>#include <algorithm>#define MAXSIZE 1001int main() {    char s1[MAXSIZE], s2[MAXSIZE];    int table[MAXSIZE<<1], *prev, *curr;    int len1,len2, i,j;    while(scanf("%s%s",s1,s2)==2) {        len1=strlen(s1), len2=strlen(s2);        prev=table, curr=&table[len2+1];        for(i=0;i<=len2+1;++i) prev[i]=0;        for(i=1;i<=len1;++i) {            for(j=1;j<=len2;++j) {                if(s1[i-1]==s2[j-1]) curr[j]=1+prev[j-1];                else curr[j]=prev[j]>curr[j-1]?prev[j]:curr[j-1];            }            std::swap(curr,prev);        }        printf("%d\n",prev[len2]);    }    return 0;}
0 0