HDU 1503 --DP

题意是给你两个单词 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 则往左走输ch2
		else if(pre[x][y]==3){lcs(x-1,y);printf("%c", ch1[x]);}//若状态为3,则往上走 输出ch1
		else {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;

	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值