• CF 346B. Lucky Common Subsequence(DP+KMP)


    这题确实很棒。。又是无想法。。其实是AC自动机+DP的感觉,但是只有一个串,用kmp就行了。

    dp[i][j][k],k代表前缀为virus[k]的状态,len表示其他所有状态串,处理出Ac[len][26]数组来,DP就可以了。状态转移那里一直没想清楚,wa了很多次,记录路径倒是不复杂,瞎搞搞就行。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 char s1[103],s2[103],virus[103];
      8 int dp[103][103][103];
      9 int pre[103][103][103];
     10 int pre1[103][103][103];
     11 int Ac[111][31];
     12 int next[103];
     13 char ans[111];
     14 void kmp()
     15 {
     16     int i,j,len,temp;
     17     len = strlen(virus);
     18     next[0] = -1;
     19     j = -1;
     20     for(i = 1; i < len; i ++)
     21     {
     22         while(j >= 0&&virus[j+1] != virus[i])
     23             j = next[j];
     24         if(virus[j+1] == virus[i]) j ++;
     25         next[i] = j;
     26     }
     27     for(i = 0; i < len; i ++)
     28     {
     29         for(j = 0; j < 26; j ++)
     30         {
     31             temp = i;
     32             while(temp >= 0&&virus[temp+1] != 'A'+j)
     33                 temp = next[temp];
     34             if(virus[temp+1] == 'A' + j) temp ++;
     35             if(temp == -1)
     36                 Ac[i][j] = len;
     37             else
     38                 Ac[i][j] = temp;
     39         }
     40     }
     41     for(i = 0; i < 26; i ++)
     42     {
     43         if(i + 'A' == virus[0])
     44             Ac[len][i] = 0;
     45         else
     46             Ac[len][i] = len;
     47     }
     48 }
     49 int main()
     50 {
     51     int i,j,k,len1,len2,len,maxz,a,b,kk;
     52     scanf("%s%s%s",s1,s2,virus);
     53     len1 = strlen(s1);
     54     len2 = strlen(s2);
     55     len = strlen(virus);
     56     kmp();
     57     for(i = 1; i <= len1; i ++)
     58     {
     59         for(j = 1; j <= len2; j ++)
     60         {
     61             for(k = 0; k <= len; k ++)
     62             {
     63                 if(k == len-1) continue;
     64                 if(dp[i][j][k] < dp[i-1][j][k])
     65                 {
     66                     dp[i][j][k] = dp[i-1][j][k];
     67                     pre[i][j][k] = 2;
     68                     pre1[i][j][k] = k;
     69                 }
     70                 if(dp[i][j][k] < dp[i][j-1][k])
     71                 {
     72                     dp[i][j][k] = dp[i][j-1][k];
     73                     pre[i][j][k] = 3;
     74                     pre1[i][j][k] = k;
     75                 }
     76                 if(s1[i-1] == s2[j-1])
     77                 {
     78                     if(Ac[k][s1[i-1]-'A'] == len-1) continue;
     79                     else if(dp[i][j][Ac[k][s1[i-1]-'A']] < dp[i-1][j-1][k] + 1)
     80                     {
     81                         dp[i][j][Ac[k][s1[i-1]-'A']] = dp[i-1][j-1][k] + 1;
     82                         pre[i][j][Ac[k][s1[i-1]-'A']] = 1;
     83                         pre1[i][j][Ac[k][s1[i-1]-'A']] = k;
     84                     }
     85                 }
     86             }
     87         }
     88     }
     89     maxz = 0;
     90     for(i = 1; i <= len1; i ++)
     91     {
     92         for(j = 1; j <= len2; j ++)
     93         {
     94             for(k = 0; k <= len; k ++)
     95             {
     96                 if(maxz < dp[i][j][k])
     97                 {
     98                     maxz = dp[i][j][k];
     99                     a = i;
    100                     b = j;
    101                     kk = k;
    102                 }
    103             }
    104         }
    105     }
    106     if(maxz == 0)
    107     {
    108         printf("0
    ");
    109         return 0;
    110     }
    111     int num = 0;
    112     //printf("%d
    ",maxz);
    113     while(a != 0&&b != 0)
    114     {
    115         if(pre[a][b][kk] == 1)
    116         {
    117             ans[num++] = s1[a-1];
    118             kk = pre1[a][b][kk];
    119             a --;
    120             b --;
    121         }
    122         else if(pre[a][b][kk] == 2)
    123         {
    124             kk = pre1[a][b][kk];
    125             a --;
    126         }
    127         else if(pre[a][b][kk] == 3)
    128         {
    129             kk = pre1[a][b][kk];
    130             b --;
    131         }
    132         else
    133             break;
    134     }
    135     for(i = num-1; i >= 0; i --)
    136     {
    137         printf("%c",ans[i]);
    138     }
    139     printf("
    ");
    140     return 0;
    141 }
  • 相关阅读:
    javascript之void0
    Sublime之OS X Command Line
    iOS之Monkey
    iOS之在成员函数中使用Block
    mac之javascriptcore
    国内成功码农的发展轨迹
    HTML之表格初步
    ClientSide JavaScript Timeline
    javascript正则表达式
    同源策略
  • 原文地址:https://www.cnblogs.com/naix-x/p/3338193.html
Copyright © 2020-2023  润新知