• HDU 4681 string 求最长公共子序列的简单DP+暴力枚举


    先预处理,用求最长公共子序列的DP顺着处理一遍,再逆着处理一遍。

    再预处理串a和b中包含串c的子序列,当然,为了使这子序列尽可能短,会以c 串的第一个字符开始 ,c 串的最后一个字符结束

    将这些起始位置先记录下来,然后枚举这些位置,最大的值输出,看一下代码,你就会顿悟了····哈哈。

    贴代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define N 1005
      5 using namespace std;
      6 char a[2][N],b[N];//a[0]为串a,a[1]为串b,b为串c
      7 int dp1[N][N],dp2[N][N];
      8 int len[3],num[2];//len[2]为串c的长度
      9 struct node
     10 {
     11     int s,e;
     12 } p[2][N];
     13 void init()//dp顺序,逆序求一次最长公共子序列
     14 {
     15     for(int i=0; i<=len[1]+1; ++i)
     16     {
     17         dp1[0][i] = 0;
     18         dp2[len[0]+1][i]=0;
     19     }
     20     for(int i=0; i<=len[0]+1; ++i)
     21     {
     22         dp1[i][0] = 0;
     23         dp2[i][len[1]+1] =0;
     24     }
     25     for(int i=1; i<=len[0]; ++i)
     26     {
     27         for(int j=1; j<=len[1]; ++j)
     28         {
     29             if(a[0][i] == a[1][j] ) dp1[i][j] = dp1[i-1][j-1]+1;
     30             else dp1[i][j] = max(dp1[i-1][j],dp1[i][j-1]);
     31         }
     32     }
     33     for(int i=len[0]; i>=1; --i)
     34     {
     35         for(int j=len[1]; j>=1; --j)
     36         {
     37             if(a[0][i]==a[1][j]) dp2[i][j]=dp2[i+1][j+1]+1;
     38             else dp2[i][j] = max(dp2[i+1][j],dp2[i][j+1]);
     39         }
     40     }
     41 }
     42 //从串中找一个包含c串的以c[0]为开始,以c[len-1]为结束的一段,记录下起始位置
     43 int pipei(int ind,int start)
     44 {
     45     int i,j=1;
     46     for(i=start+1; i<=len[ind]; ++i)
     47     {
     48         if(a[ind][i] == b[j]) ++j;
     49         if(j==len[2]) break;
     50     }
     51     if(j <len[2]) return -1;
     52     else return i;
     53 }
     54 //预处理出a串和b串中所有如上所述的子串的起始位置
     55 void yumeiju(int ind)
     56 {
     57     num[ind] = 0;
     58     for(int i=1; i<=len[ind]; ++i)
     59     {
     60         if(a[ind][i] == b[0])
     61         {
     62             int e = pipei(ind,i);
     63             if(e == -1) continue;
     64             p[ind][num[ind]].s=i;
     65             p[ind][num[ind]].e = e;
     66             ++num[ind];
     67         }
     68     }
     69 }
     70 //枚举所有的可能,求解
     71 int meiju()
     72 {
     73     init();
     74     yumeiju(0);
     75     yumeiju(1);
     76     int ans=0;
     77     for(int i=0; i<num[0]; ++i)
     78     {
     79         for(int j=0; j<num[1]; ++j)
     80         {
     81             if(dp1[p[0][i].s-1][p[1][j].s-1] + dp2[p[0][i].e+1][p[1][j].e+1] > ans)
     82                 ans = dp1[p[0][i].s-1][p[1][j].s-1] + dp2[p[0][i].e+1][p[1][j].e+1] ;
     83         }
     84     }
     85     return ans +len[2];
     86 }
     87 int main()
     88 {
     89 //    freopen("in.txt","r",stdin);
     90     int t;
     91     scanf("%d",&t);
     92     a[0][0]='#';
     93     a[1][0] ='#';
     94     for(int ser =1; ser<=t; ++ser)
     95     {
     96         scanf("%s%s%s",a[0]+1,a[1]+1,b);
     97         len[0]= strlen(a[0])-1;
     98         len[1] = strlen(a[1])-1;
     99         len[2] = strlen(b);
    100         printf("Case #%d: %d
    ",ser,meiju());
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    命令行方式执行YUITest单元测试
    Rails系统重构:从单一复杂系统到多个小应用集群
    hudson部署设置 Spring——Java程序员的春天 ITeye技术网站
    java获取本机IP
    2.5.如何创建JAR以及把它安装到本地库中?
    管理员常用的管理工具有哪些?
    PHP学习之十四:构造函数
    window phone 7开发之 项目初体验
    window phone7开始之 横屏竖屏
    Silverlight 硬件加速
  • 原文地址:https://www.cnblogs.com/allh123/p/3264040.html
Copyright © 2020-2023  润新知