HDU-1159 -Common Subsequence

来源:互联网 发布:steam淘宝买游戏 编辑:程序博客网 时间:2024/05/29 19:26

点击查看详情——《IJCAI 2017 口碑商家客流量预测大赛》

Common Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 36329    Accepted Submission(s): 16631


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 abfcabprogramming contest abcd mnp
 

Sample Output
420
 

Source
Southeastern Europe 2003
 

Recommend
Ignatius

这道题也是简单的DP 
我觉得DP最重要还是思路,因为代码很短的,很好实现,但是方法很难想
如果DP都能想出状态转移方程,那就NB了
(1)大部分DP的思路就是如何找最优解,并更新最优解
这题的思路就是,如果发现有相同的字母,那么就更新最优解,
那么从哪里更新最优解那? 当然从上一次的dp中更新就是 dp【i-1】【j-1】
这是算前dp【i-1】【j-1】是前i -1个字母的最优解,那么就在这上面加1
还有,没一个字母只能对应一个字母,不能多对一,那么你还要排重
(2)如果没发现相同的字母,还是要找最优解,从map[i-1][j-1],map[i-1][j],map[i][j-1]中找最大的
那么为什么要从这3个中找最大的那?
其实这三个数都表示上一步的最优解 为了容易区分我  先输入的字符串为s1  后输入的为s2
dp[i-1][j-1]其实是 输入s1第  i-1个字符  并比较到 s2 第 j-1 个字符的最优解
dp[i-1][j]  其实是输入 s1第 i-1个字符,并比较到 s2第j个字符的最优解
dp[i][j-1] 其实是输入s1第i个字符,并比较到s2第 j-1 个字符的最优解
(3)上面这段话看不懂,没关系,简单来说;
把两个字符串比较,看成s1输入一个字符比较,然后s2再输入一个字符,再比较,然后s1再输入第二个字符,同理s2
每输入一次,就要比较一下,找出当前的最优解,这三个最优解分别表示当前解的前三次dp,找出最优的
那推理一下,其实我只要找连个就行了,对的,其实只要找map[i][j-1]和map[i-1][j];
注意,只找前1个会WA的
     a    b     e                             a      e      f
a   1   1     1                       a    1      1      1
e   1   1     2                       b     1     1      1
 f    1  1     2                       e     1      2      2
可以配合这个表看一下,这就是打表出的结果
一组数据调换一下顺序,就可以看出为什么要至少找两个,还要找这两个的原因

下面上代码

#include<stdio.h>#include<string.h>char a[1000],b[1000];int map[1000][1000];int max(int a,int b){    if(a>=b)        return a;    else        return b;}int main(){    int len1,len2,pos=1,flag=0;    while(scanf("%s%s",a,b)!=EOF)    {        int num=-1;        len1=strlen(a);        len2=strlen(b);        memset(map,0,sizeof(map));        for(int i=1; i<=len1; i++)        {            for(int j=pos; j<=len2; j++)            {                flag=0;                if(a[i-1]==b[j-1]&&flag==0)                {                    map[i][j]=map[i-1][j-1]+1;                    flag=1;                }                else                {                    map[i][j]=max(map[i][j-1],map[i-1][j]);                }                if(map[i][j]>num)                {                    num=map[i][j];                }            }            /*for(int k=1;k<=len2;k++)     //²âÊÔÊý¾Ý            {                printf("%d ",map[i][k]);            }            printf("\n");*/        }        printf("%d\n",map[len1][len2]);    }    return 0;}




0 0
原创粉丝点击