HDU--杭电--1501--Zipper--深搜、DP都好
来源:互联网 发布:淘宝店需要购买软件吗 编辑:程序博客网 时间:2024/05/17 01:12
Zipper
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5807 Accepted Submission(s): 2086
Problem Description
Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.
For example, consider forming "tcraete" from "cat" and "tree":
String A: cat
String B: tree
String C: tcraete
As you can see, we can form the third string by alternating characters from the two strings. As a second example, consider forming "catrtee" from "cat" and "tree":
String A: cat
String B: tree
String C: catrtee
Finally, notice that it is impossible to form "cttaree" from "cat" and "tree".
For example, consider forming "tcraete" from "cat" and "tree":
String A: cat
String B: tree
String C: tcraete
As you can see, we can form the third string by alternating characters from the two strings. As a second example, consider forming "catrtee" from "cat" and "tree":
String A: cat
String B: tree
String C: catrtee
Finally, notice that it is impossible to form "cttaree" from "cat" and "tree".
Input
The first line of input contains a single positive integer from 1 through 1000. It represents the number of data sets to follow. The processing for each data set is identical. The data sets appear on the following lines, one data set per line.
For each data set, the line of input consists of three strings, separated by a single space. All strings are composed of upper and lower case letters only. The length of the third string is always the sum of the lengths of the first two strings. The first two strings will have lengths between 1 and 200 characters, inclusive.
For each data set, the line of input consists of three strings, separated by a single space. All strings are composed of upper and lower case letters only. The length of the third string is always the sum of the lengths of the first two strings. The first two strings will have lengths between 1 and 200 characters, inclusive.
Output
For each data set, print:
Data set n: yes
if the third string can be formed from the first two, or
Data set n: no
if it cannot. Of course n should be replaced by the data set number. See the sample output below for an example.
Data set n: yes
if the third string can be formed from the first two, or
Data set n: no
if it cannot. Of course n should be replaced by the data set number. See the sample output below for an example.
Sample Input
3cat tree tcraetecat tree catrteecat tree cttaree
Sample Output
Data set 1: yesData set 2: yesData set 3: no
思路:本题有缺陷,就是测试数据弱爆了,所以直接暴力深搜加几个特解就能过,不过暴力深搜的就没给代码了,直接是平常深搜的代码,然后是DP的代码,解释在代码中
深搜:
#include <iostream>#include <cstring>using namespace std;char s1[222],s2[222],s3[444];int l1,l2,visit[222][222];bool dfs(int i,int j,int k){ if(k==l1+l2)return 1;//s3的下标等于s1加s2长度的时候就表示搜完了 if(visit[i][j])return 0;//这一步很重要,没了他就超时,深搜讲究的就是不重复搜同一个点 visit[i][j]=1; if(i<l1&&s1[i]==s3[k]&&dfs(i+1,j,k+1))return 1;//s1能和s3匹配就递归一次,返回值为1就接着返回,因为返回1表示的就是找到了对的路了 if(j<l2&&s2[j]==s3[k]&&dfs(i,j+1,k+1))return 1;//s2能和s3匹配也递归一次 return 0;}int main (void){ int n,i,j,k=1; cin>>n; while(n--&&cin>>s1>>s2>>s3) { l1=strlen(s1); l2=strlen(s2); for(i=0;i<222;i++)//初始化标记数组 for(j=0;j<222;j++) visit[i][j]=0; cout<<"Data set "<<k++<<": "; if(dfs(0,0,0))cout<<"yes"<<endl;//直接从三个字符串的第一个开始深搜 else cout<<"no"<<endl; } return 0;}
DP://DP的想法就是DP[i][j]代表s1[i]和s2[j]这两个点同ss[i+j]匹配的当前状态
如匹配catrtee,不看其他杂乱的最终就得到这样个图(实际上还有些数字,因为可能是从中间开始匹配成功的)
c a t
0 1 2 0
t 0 0 3 0
r 0 0 4 5
e 0 0 0 6
e 0 0 0 7
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int l1,l2,l3;char s1[444],s2[444],ss[444];int main (void){ int i,j,n,m=1,dp[222][222]; scanf("%d",&n); while(n--&&scanf("%s%s%s",s1,s2,ss)) { memset(dp,0,sizeof(dp)); l1=strlen(s1); l2=strlen(s2); l3=strlen(ss); if(ss[0]==s1[0])dp[1][0]=1;//如果s1第一个和ss配上就标记初始状态“s1成功一个,s2成功0个”为1if(ss[0]==s2[0])dp[0][1]=1;//同上 for(i=0;i<=l1;i++)//有了初始状态之后就进行下面的递归 for(j=0;j<=l2;j++) { if(i>0&&s1[i-1]==ss[i+j-1])//s1没完,就用s1来匹配 dp[i][j]=max(dp[i][j],dp[i-1][j]+1);//取当前点的值与由前一个状态递推过来的值的最大值,因为有的从中间开始匹配成功的树值会干扰结果 if(j>0&&s2[j-1]==ss[i+j-1]) dp[i][j]=max(dp[i][j],dp[i][j-1]+1); } printf("Data set %d: ",m++); if(dp[l1][l2]==l3) cout<<"yes"<<endl; else cout<<"no"<<endl; } return 0;}
0 0
- HDU--杭电--1501--Zipper--深搜、DP都好
- Zipper - HDU 1501 dp
- hdu 1501 Zipper dp
- HDU 1501 Zipper DP -
- 杭电1501 Zipper
- hdu 1501 Zipper(DP)
- HDU-1501 Zipper 简单DP
- HDU 1501 Zipper(DP,DFS)
- HDU 1501 Zipper(DP,DFS)
- HDU 1501 Zipper(dp)
- 杭电1501 Zipper DFS
- hdu 1501 Zipper(dfs或dp)
- 杭电1501 hdu1501 Zipper(深搜dfs)
- 杭电 1501 zipper(典型dfs)
- HDU 1501 & POJ 2192 Zipper(dp记忆化搜索)
- HDU-1501 (POJ-2192) Zipper (DFS||DP)
- hdu 1501 Zipper
- hdu 1501 Zipper--LCS
- Windows系统CPU内存网络性能统计第一篇 内存
- 进程组与会话
- iphone开发之轻松搞定原生socket 编程,阻塞与非阻塞,收发自如
- C++通过DLL调用C#代码
- iOS - 第三方库 SAVideoRangeSlider 的代码学习记录
- HDU--杭电--1501--Zipper--深搜、DP都好
- 字符界面编程利器——vim + ctag + Taglist
- iOS-重力感应
- Windows Azure 安全最佳实践 - 第 5 部分:基于Claim 的标识,单点登录
- C/C++变量在内存中的分布
- Windows 各种计时函数总结
- c++ 笔试题(部分)
- VC Debug与Release区别
- 架构设计中服务层的简单理解(转载)