hdu 1159 动态规划初步

来源:互联网 发布:黑马播放器 for mac 编辑:程序博客网 时间:2024/06/06 03:20

题目

Problem Description A subsequence of a given sequence is the given
sequence with some elements (possible none) left out. Given a sequence
X = < x1, x2, …, xm > another sequence Z = < z1, z2, …, zk > is a
subsequence of X if there exists a strictly increasing sequence < i1,
i2, …, ik > of indices of X such that for all j = 1,2,…,k, xij =
zj. For example, Z = < a, b, f, c> is a subsequence of X = < a, b, c, f,
b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y
the problem is to find the length of the maximum-length common
subsequence of X and Y. The program input is from a text file. Each
data set in the file contains two strings representing the given
sequences. The sequences are separated by any number of white spaces.
The input data are correct. For each set of data the program prints on
the standard output the length of the maximum-length common
subsequence from the beginning of a separate line.

Sample Input abcfbc abfcab programming contest abcd mnp

Sample Output 4 2 0

翻译

求最长的公共字符串
注意是所有元素重新组成的集合在原集合中的顺序与此无关

题目讲解

以例一为例子画二维图

可以看到如果横向和纵向的字符一样那么原有数值加1
如果横向和纵向的字符不同那么他的上方和左方的数字取最大的继续写入

分析以上两句话:
1.可以证明一下几点:
(1).对角线的数值一定最大(如果不相同对角线的数值应该是上和左的最大值,如果相同则加一 递推可得以上结论)
(2).因为对角线的数值最大所以涵盖了全部的尝试所以对角线上的数可以表示两个字符串的最长公共子序列
2.对于上两点我们需要做到以下几步:
(1).新建两个以为数组来分别存储两个字符串
(2). 新建一个二维数组来代表如上图所示的二维图片
(3). 注意以上3个数组为减少麻烦推荐空出 a[0], b[0] c[0][0], c[0][1],c[1][0]
(4).在实现第2步的时候注意 有关字符串的函数其参数都应该+1 srtlen(a + 1);
(5).在递推的过程中如果遇到a[i] == b[j] 的那么 c[i][j] = c[i - 1][j - 1] + 1;
如果遇到a[i] != b[j] 那么c[i][j] = max(c[i - 1][j], c[j - 1][i]);

类型讲解(动态规划初步)

            if (s1[i] == s2[j])                c[i][j] = c[i - 1][j - 1] + 1;            else                c[i][j] = max(c[i - 1][j], c[i][j - 1]);

分析+ 代码

#include<stdio.h>#include<string.h>char s1[1009], s2[1009];int c[1009][1009];int max(int a, int b){    return a > b ? a : b;}int main(){    int i, j, n, m;    while (scanf("%s %s", s1 + 1, s2 + 1) != EOF)//字符编号从1开始!    {        n = strlen(s1 + 1);        m = strlen(s2 + 1);        for (i = 1; i <= n; i++)            c[i][0] = 0;        for (j = 1; j <= m; j++)            c[0][j] = 0;        for (i = 1; i <= n; i++)            for (j = 1; j <= m; j++)            {                if (s1[i] == s2[j])                    c[i][j] = c[i - 1][j - 1] + 1;                else                    c[i][j] = max(c[i - 1][j], c[i][j - 1]);            }        printf("%d\n", c[n][m]);    }    return 0;}
0 0