zoukankan      html  css  js  c++  java
  • Codeforces Round#201(div1) D. Lucky Common Subsequence

    题意:给定两个串,求出两个串的最长公共子序列,要求该公共子序列不包含virus串。

    用dp+kmp实现

    dp[i][j][k]表示以i结尾的字符串和以j结尾的字符串的公共子序列的长度(其中k表示该公共子序列的与virus的匹配程度)很显然,当k==strlen(virus)时,该公共子序列不是我们所求得

     当添加一个字符时,如果失配,这时不能让k直接等于0,而是要用kmp给k一个合理的值。

      1 #include <stdio.h>
      2 #include <string.h>
      3 const int N = 100 + 10;
      4 int dp[N][N][N];
      5 int pre[N][N][N][3];
      6 char s1[N],s2[N],vir[N];
      7 int next[N];
      8 char ans[N];
      9 void makeNext(int n)
     10 {
     11     next[0] = -1;
     12     int i = 0,j=-1;
     13     while(i < n)
     14     {
     15         if(j==-1 || vir[i] == vir[j])
     16         {
     17             i++;
     18             j++;
     19             next[i] = j;
     20         }
     21         else
     22             j = next[j];
     23     }
     24 }
     25 void DP(int x, int y, int z, int x1, int y1, int z1, int val)
     26 {
     27     if(dp[x][y][z] < dp[x1][y1][z1] + val)
     28     {
     29         dp[x][y][z] = dp[x1][y1][z1] + val;//状态转移
     30         //保存路径
     31         pre[x][y][z][0] = x1;
     32         pre[x][y][z][1] = y1;
     33         pre[x][y][z][2] = z1;
     34     }
     35 }
     36 int main()
     37 {
     38     int i,j,k;
     39     scanf("%s%s%s",s1+1,s2+1,vir);
     40     int len1 = strlen(s1+1);
     41     int len2 = strlen(s2+1);
     42     int len3 = strlen(vir);
     43     memset(dp,0,sizeof(dp));
     44     memset(pre,-1,sizeof(pre));
     45     makeNext(len3);
     46     for(i=1; i<=len1; ++i)
     47         for(j=1; j<=len2; ++j)
     48         {
     49             for(k=0; k<len3; ++k)
     50             {
     51                 DP(i,j,k,i-1,j,k,0);//s1[i] != s2[j]时的转移
     52                 DP(i,j,k,i,j-1,k,0);
     53                 if(s1[i] == s2[j])//s1[i] == s2[j]
     54                 {
     55                     if(s1[i] == vir[k])
     56                     {
     57                         DP(i,j,k+1,i-1,j-1,k,1);
     58                     }
     59                     else
     60                     {
     61                         int p = next[k];
     62                         while(p!=-1 && s1[i] != vir[p]) p = next[p];
     63                         if(p==-1)
     64                             p = 0;
     65                         if(s1[i] == vir[p])
     66                             DP(i,j,p+1,i-1,j-1,k,1);
     67                         else
     68                             DP(i,j,p,i-1,j-1,k,1);
     69                     }   
     70                 }
     71             }
     72         }
     73     int z;
     74     int Max = -1;
     75     for(k=0; k<len3; ++k)
     76         if(Max < dp[len1][len2][k])
     77         {
     78             Max = dp[len1][len2][k];
     79             z = k;
     80         }   
     81     if(Max <= 0)
     82         printf("0
    ");
     83     else//根据路径求出最长公共子序列
     84     {
     85         int tMax = Max;
     86         int x = len1,y = len2;
     87         while(pre[x][y][z][0] != -1)
     88         {
     89             int xx = pre[x][y][z][0];
     90             int yy = pre[x][y][z][1];
     91             int zz = pre[x][y][z][2];
     92             if(x-xx==1 && y-yy==1&&s1[x] == s2[y]) 
     93                 ans[Max--] = s1[x];
     94             x = xx;y=yy;z=zz;
     95         }
     96         for(i=1; i<=tMax; ++i)
     97             printf("%c",ans[i]);
     98         printf("
    ");
     99     }
    100 }
    View Code
  • 相关阅读:
    SQL语句导入导出大全
    数据库连接大全
    数据库关键字过滤问题
    HttpHandler
    asp代码的一个do。。。wile循环代码
    vs .net 2005 的Global.asax 在哪添加
    asp.net项目ckeditor+ckfinder实现图片上传
    CKEditor+CKFinder的图片上传配置
    asp实现统计访问量的代码
    asp.net绘统计图
  • 原文地址:https://www.cnblogs.com/justPassBy/p/3963200.html
Copyright © 2011-2022 走看看