HDU 1503 --DP

来源:互联网 发布:onavo mac版 编辑:程序博客网 时间:2024/04/30 23:20

题意是给你两个单词 ch1、ch2   让你拼成一个单词ch ,ch1 和ch2 分别都是ch的子序列。并要求ch的长度最小 ,输出ch。


根据LCS原理 ,先找出最长公共子序列,对其转移的路线进行记录,然后用递归输出。


#include <stdio.h>#include <iostream>#include <cstring>#include <algorithm>using namespace std;char ch1[110],ch2[110];int dp[110][110];int pre[110][110];//输出void lcs(int x,int y){//到0,0时跳出if(x==0&&y==0)return; if(pre[x][y]==1){lcs(x,y-1);printf("%c",ch2[y]);}//若状态为1 则往左走输ch2else if(pre[x][y]==3){lcs(x-1,y);printf("%c", ch1[x]);}//若状态为3,则往上走 输出ch1else {lcs(x-1,y-1);printf("%c",ch1[x]);}//状态为2,则表明当前的ch1[x],ch2[y]是相等的 随便输出一个就可以。}int main(){freopen("in.in","r",stdin);while(scanf("%s %s",ch1,ch2)!=EOF){int len1 ,len2;len1=strlen(ch1);len2=strlen(ch2);memset(dp,0,sizeof(dp));memset(pre,0,sizeof(pre));for(int i=len1;i>0;i--) ch1[i]=ch1[i-1];for(int i=len2;i>0;i--) ch2[i]=ch2[i-1];    for(int l=0;l<=len1;l++) {pre[l][0]=3;}        for(int l=0;l<=len2;l++) {pre[0][l]=1;}for(int i=1;i<=len1;i++){for(int j=1;j<=len2;j++){if(ch1[i]==ch2[j]) {dp[i][j]=dp[i-1][j-1]+1;pre[i][j]=2;}else if(dp[i-1][j]<dp[i][j-1]) {dp[i][j]=dp[i][j-1];pre[i][j]=1;}else {dp[i][j]=dp[i-1][j];pre[i][j]=3;}}}lcs(len1,len2);printf("\n");memset(ch1,'\0',sizeof(ch1));memset(ch2,'\0',sizeof(ch2));}return 0;}


0 0