*【HDU - 5707】Combine String(dp)

题干:

Given three strings aa, bb and cc, your mission is to check whether cc is the combine string of aa and bb. 
A string cc is said to be the combine string of aa and bb if and only if cc can be broken into two subsequences, when you read them as a string, one equals to aa, and the other equals to bb. 
For example, ``adebcf'' is a combine string of ``abc'' and ``def''. 

Input

Input file contains several test cases (no more than 20). Process to the end of file. 
Each test case contains three strings aa, bb and cc (the length of each string is between 1 and 2000). 

Output

For each test case, print ``Yes'', if cc is a combine string of aa and bb, otherwise print ``No''. 

Sample Input

abc
def
adebcf
abc
def
abecdf

Sample Output

Yes
No

解题报告:

  可以直接bool类型的dp[i][j]代表第一个串前i个和第二个串前j个可否匹配的。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
char a[MAX],b[MAX],c[MAX];
bool dp[2222][2222];
int main()
{
	while(~scanf("%s%s%s",a+1,b+1,c+1)) {
		int la = strlen(a+1);
		int lb = strlen(b+1);
		int lc = strlen(c+1);
		if(la+lb!=lc) {
			puts("No");continue;
		}
		memset(dp,0,sizeof dp);
		dp[0][0]=1;
		for(int i = 1; i<=la; i++) if(c[i] == a[i]) dp[i][0] |= dp[i-1][0];
		for(int i = 1; i<=lb; i++) if(c[i] == b[i]) dp[0][i] |= dp[0][i-1]; 
		for(int i = 1; i<=la; i++) {
			for(int j = 1; j<=lb; j++) {
				if(c[i+j] == a[i]) dp[i][j] |= dp[i-1][j];
				if(c[i+j] == b[j]) dp[i][j] |= dp[i][j-1];
			}
		}
		if(dp[la][lb]) puts("Yes");
		else puts("No");
	}
	return 0 ;
}

 

但是比赛的时候硬是让我写了个序列自动机+dp。

dp[i][j]代表第一个串前i个和第二个串前j个匹配,需要达到的最小位置。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2000 + 5;
char a[MAX],b[MAX],c[MAX];
int dp[MAX][MAX],trie[MAX][222];
int main()
{
	while(~scanf("%s",a+1)) {		
		scanf("%s",b+1);
		scanf("%s",c+1);
		memset(dp,0x3f,sizeof dp);
		dp[0][0]=0;
		int la = strlen(a+1),lb = strlen(b+1),lc = strlen(c+1); 
		if(la+lb!=lc) {
			puts("No");continue;
		}
		for(int i = 0; i<=129; i++) trie[lc+1][i]=trie[lc+2][i] = lc+1;
		for(int i = lc; i>=1; i--) {
			int cur = c[i] ;
			for(int j = 0; j<129; j++) {
				if(j == cur) trie[i][j] = i;
				else trie[i][j] = trie[i+1][j];
			}
		}
		for(int i = 1; i<=la; i++) dp[i][0] = trie[dp[i-1][0]+1][a[i]];
		for(int i = 1; i<=lb; i++) dp[0][i] = trie[dp[0][i-1]+1][b[i]];
		for(int i = 1; i<=la; i++) {
			for(int j = 1; j<=lb; j++) {
				dp[i][j] = min(dp[i][j],trie[dp[i-1][j]+1][a[i]]);
				dp[i][j] = min(dp[i][j],trie[dp[i][j-1]+1][b[j]]);
			}
		}
		if(dp[la][lb] != lc) puts("No");
		else puts("Yes");
	}


	return 0 ;
}

 

全部评论

相关推荐

12-13 20:26
浙江大学 Java
淬月星辉:把浙大的校名加大加粗,把校徽再贴出来,就OK了
点赞 评论 收藏
分享
StephenZ_:我9月份找的第一段实习也是遇到这种骗子公司了,问他后端有多少人和我说7个正职,进去一看只有一个后端剩下的都是产品前端算法(没错甚至还有算法)。还是某制造业中大厂,我离职的时候还阴阳怪气我
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务