• POJ-1458 最长公共子序列


    这个题的意思就是说:

    给一个序列 A 和 B ,让你求他们的共同的子序列的长度,这些子序列可以不在原来的字符串中连续排列。

    这个题的话,我们可以使用动态规划的思路,我们假设 MaxLen [ i ] [ j ] 是 A 串和 B 串中从一开始的,A 串中的的第 i 个字符和B 串中的第 j 个字符的最长公共子序列的长度。

    我们可以知道 MaxLen[i][0]是0,并且 MaxLen[0][j]也是0,这是边界条件。

    然后对于以后的如果 a串的第 i个字符和 b串的第 j个字符相等的话,我们就可以让 MaxLen [i][j]加一,如果不相等的话我们就从

    maxlen[i][j-1] 和maxlen[j][i-1]中选一个大的出来作为它的值。

    对于一个不做证明,第二个也很好证明,主要是因为,既然 MaxLen [i][j] 不大于MaxLen [i][j-1]和 MaxLen [i-1][j],并且 MaxLen [i][j]

    不小于 MaxLen [i][j-1] 和 MaxLen [i-1][j] ,所以,他们可以说是相等的关系。

    怎么证明这个,对于不小于不再作证明了,不大于的话我们用反证就可以了。

    因为如果它大于 减一 这个类的话,说明,第 i 个字符起作用了,因为 i-1 并没有这个字符,说明它就是最后一个字符,同理 j-1也是最后一个字符,既然他们都是最后一个字符,并且都起了作用, 说明他们相等,而我们的前提是 i-1 不等于 j-1,所以推出矛盾,假设不成立。

    #include <iostream>
    #include <cstring>
    using namespace std;
    char sz1[1000];
    char sz2[1000];
    int MaxLen[1000][1000]; 
    using namespace std;
    int main()
    {
    	while (cin>>sz1>>sz2) {
    		int len1=strlen(sz1);
    		int len2=strlen(sz2);
    		for (int i=0;i<=len1;i++) {
    			MaxLen[i][0]=0;
    		}
    		for (int j=0;j<=len2;j++) {
    			MaxLen[0][j]=0;
    		}
    		for (int i=1;i<=len1;i++) {
    			for (int j=1;j<=len2;j++) {
    				if (sz1[i-1]==sz2[j-1]) {
    					MaxLen[i][j]=MaxLen[i-1][j-1]+1;
    				}
    				else {
    					MaxLen[i][j]=max(MaxLen[i-1][j],MaxLen[i][j-1]);
    				}
    			}
    		}
    		cout<<MaxLen[len1][len2]<<endl;
    	}
    	return 0;
    }
  • 相关阅读:
    假期学习总结2-14
    假期学习总结2-13
    假期总结2-12
    假期总结2-11
    读人月神话
    冲刺第五天 11.29 THU
    冲刺第四天 11.28 WED
    冲刺第三天 11.27 TUE
    冲刺第二天 11.26 MON
    冲刺第一天 11.23 FRI
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/10211359.html
Copyright © 2020-2023  润新知