hdu1501 (dp)

大致题意:有A,B,C三个字符串。判断C字符串是否由A和B中的所有字符组成。并且,A和B中的字符串在C中的位置是不变的。

例如:cat tree tcraete   C字符串可由A,B构成

        cat tree cttaree    由于位置改变了,所以C就不能由A,B组成了。

分析:两种解法:一搜索。二dp。

dp:我们把ab字符串想象为一个 lena  X  lenb  的矩阵。然而c字符串则是这个矩阵里面的一条通路。我们需要判断的就是这条通路是否存在。

可以知道c中的第(i+j)个字符要么等于a[i],要么等于b[j]。也就是说dp[i][j]=((dp[i-1][j]&&a[i]==c[i+j])||(dp[i][j-1]&&b[j]==c[i+j]))。

那么dp的初始化肯定在这里:

1         for(i=1;i<=lena;i++)
2             if(a[i]==c[i])  dp[i][0]=1;//在第0行和第0列,如果有匹配到c字符串中的字符便把dp[0][i]或dp[i][0]置为1,否则为0.这就算dp的初始值。
3             else dp[i][0]=0;
4         for(i=1;i<=lenb;i++)
5             if(b[i]==c[i])  dp[0][i]=1;
6             else dp[0][i]=0;

 

还是看代码分析吧:dp[i][i]:如果值为1代表a[i]==c[i+j]或者b[j]==c[i+j]成立。否则不成立

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 char a[205],b[205],c[405];
 5 int dp[205][205];
 6 int main()
 7 {
 8     int T;
 9     scanf ("%d",&T);
10     for(int t=1;t<=T;t++)
11     {
12         a[0]=b[0]=c[0]='0';
13         scanf ("%s %s %s",a+1,b+1,c+1);//我们刻意让字符串的起始地址为1
14         int lena=strlen(a)-1;
15         int lenb=strlen(b)-1;
16         int i,j,k;
17         for(i=1;i<=lena;i++)
18             if(a[i]==c[i])  dp[i][0]=1;
19             else dp[i][0]=0;
20         for(i=1;i<=lenb;i++)
21             if(b[i]==c[i])  dp[0][i]=1;
22             else dp[0][i]=0;
23         for(i=1;i<=lena;i++)
24         {
25             for(j=1;j<=lenb;j++)
26             {
27                 dp[i][j]=((dp[i-1][j]&&a[i]==c[i+j])||(dp[i][j-1]&&b[j]==c[i+j]));//递推求dp的值
28             }
29         }
30         /*for(i=0;i<=lena;i++)
31         {
32             for(j=0;j<=lenb;j++)
33                 printf("%d ",dp[i][j]);
34             printf("\n");
35         }*/
36         printf("Data set %d: ",t);
37         if(dp[lena][lenb])
38             printf("yes\n");
39         else
40             printf("no\n");
41     }
42     return 0;
43 }

搜索解:

代码如下:

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 char a[205],b[205],c[405];
 5 int la,lb,lc,flag;
 6 int visit[205][205];
 7 void dfs(int i,int j,int k)
 8 {
 9     if(k==lc)//当然,如果搜索到k等于c的长度的话,那么肯定是yes了
10     {
11         flag=1;
12         return ;
13     }
14     if(visit[i][j])//为什么要加visit数组,我觉得是记忆化搜索。
15         return ;
16     visit[i][j]=1;
17 
18     if(a[i]!=c[k]&&b[j]!=c[k])//如果c的k这个位置a和b都不符合。那么就return。
19         return ;
20     if(a[i]==c[k]&&i+1<=la)//如果a[i]==c[k]而且i+1小于a的长度la的话,进入下一个字符。
21         dfs(i+1,j,k+1);
22     if(b[j]==c[k]&&j+1<=lb)//同理
23         dfs(i,j+1,k+1);
24 }
25 int main()
26 {
27     int T;
28     scanf ("%d",&T);
29     for(int t=1;t<=T;t++)
30     {
31         scanf ("%s %s %s",a,b,c);
32         la=strlen(a);
33         lb=strlen(b);
34         lc=strlen(c);
35         flag=0;
36         memset(visit,0,sizeof(visit));//对visit初始化
37         dfs(0,0,0);
38         if(flag)
39             printf("Data set %d: yes\n",t);
40         else
41             printf("Data set %d: no\n",t);
42     }
43     return 0;
44 }

搜索和dp基础。一定要多练。

posted on 2015-04-23 00:32  Bei_insomia  阅读(139)  评论(0编辑  收藏  举报

导航