首页 > 代码库 > nyoj 36 最长公共子序列 【DP】

nyoj 36 最长公共子序列 【DP】

今天听了老师讲的最长公共子序列,就拿以前做过的题又做了一遍。。。

我用的是最简单普通的方法,

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[1005][1005];
int main()
{
	char a[1005], b[1005];
	int t;
	scanf("%d", &t);
	while(t --){
		scanf("%s", a);
		scanf("%s", b);
		int la = strlen(a);
		int lb = strlen(b);
		memset(dp, 0, sizeof(dp));
		int i, j;
	//	printf("%d %d\n", la, lb);
		for(i = 1; i <= la; i ++){
			for(j = 1; j <= lb; j ++){
				if(a[i-1] == b[j-1]) dp[i][j] = dp[i-1][j-1]+1; 
				else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);//printf("%d..", dp[i][j]);
			}
		//	putchar('\n');
		}
		printf("%d\n", dp[la][lb]);
	}
	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;
}