• 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("
    ");
    35         }*/
    36         printf("Data set %d: ",t);
    37         if(dp[lena][lenb])
    38             printf("yes
    ");
    39         else
    40             printf("no
    ");
    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
    ",t);
    40         else
    41             printf("Data set %d: no
    ",t);
    42     }
    43     return 0;
    44 }

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

  • 相关阅读:
    反射获取class的Class
    线程礼让yield和线程的强制执行join
    Lambda表达式
    java中的静态代理
    java多线程中的callable接口实现
    java利用线程并行的方法模拟龟兔赛跑
    java中的多线程
    HTTP 协议之请求格式
    java的反射概述
    Tomcat和servlet的关系
  • 原文地址:https://www.cnblogs.com/bei-insomia/p/4449128.html
Copyright © 2020-2023  润新知