zoukankan      html  css  js  c++  java
  • luogu P1026 统计单词个数 序列DP

    dp[i][k]表示,在i及i左侧,分成k块,的最大单词数目。

    w[i][j]表示,在[i,j],内部多少个单词在此区间开始和结束。

    转移方程为dp[i][k] = max(dp[j][k - 1] + w[j + 1][i])

    通过考虑每个单词的结束而非开始,而避开后后效性问题。

    如果某个单词是另一个单词的前缀,则另一个单词无需考虑。

    字符串处理的有问题,调了挺久的....

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 int n,k,len,tot,root,p;
     6 int dp[210][50],w[210][210],ch[1000][30];
     7 char s[210],str[210];
     8 bool end[1000];
     9 void add(char *voc)
    10 {
    11     int l = strlen(voc + 1),u = root;
    12     for (int i = 1;i <= l;i++)
    13     {
    14         if (end[u] == true)
    15             break;
    16         if (ch[u][voc[i] - 'a'] != 0)
    17             u = ch[u][voc[i] - 'a'];
    18         else
    19             u = ch[u][voc[i] - 'a'] = ++tot;
    20     }
    21     end[u] = true; 
    22 }
    23 int main()
    24 {
    25     root = tot = 1;
    26     scanf("%d%d",&n,&k);
    27     for (int i = 1;i <= n;i++)
    28         scanf("%s",s + (i - 1) * 20 + 1);
    29     len = strlen(s + 1);
    30     scanf("%d",&p);
    31     for (int i = 1;i <= p;i++)
    32     { 
    33         scanf("%s",str + 1);
    34         add(str);
    35     } 
    36     for (int i = 1;i <= len;i++)
    37     {
    38         for (int j = i;j <= len;j++)
    39         {
    40             w[i][j] += w[i][j - 1];
    41             int u = root,t = j;
    42             while (u != 0)
    43             {
    44                 u = ch[u][s[t] - 'a'];
    45                 if (end[u] == true)
    46                 {
    47                     w[i][t]++;
    48                     break;
    49                 }
    50                 t++;
    51             }
    52         }
    53     }
    54     for (int i = 1;i <= len;i++)
    55         dp[i][1] = w[1][i];
    56     for (int o = 2;o <= k;o++)
    57         for (int i = o;i <= len;i++)
    58             for (int j = o - 1;j <= i - 1;j++)
    59                 dp[i][o] = max(dp[j][o - 1] + w[j + 1][i],dp[i][o]);
    60     printf("%d",dp[len][k]);
    61 }
    心之所动 且就随缘去吧
  • 相关阅读:
    软件工程评分表
    评论
    团队成员介绍
    第九天冲刺
    第八天冲刺
    第七天冲刺
    第六天冲刺
    第五天冲刺
    第四天冲刺
    第三天冲刺
  • 原文地址:https://www.cnblogs.com/iat14/p/10658171.html
Copyright © 2011-2022 走看看