• 统计单词个数


    题目描述

    给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份(1<k≤40),

    且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串this中可包含thisis,选用this之后就不能包含th)。

    单词在给出的一个不超过6个单词的字典中。

    要求输出最大的个数。

    输入输出格式

    输入格式:

    每组的第一行有2个正整数(p,k)

    p表示字串的行数,k表示分为k个部分。

    接下来的p行,每行均有20个字符。

    再接下来有1个正整数s,表示字典中单词个数。(1s6)

    接下来的s行,每行均有1个单词。

    输出格式:

    1个整数,分别对应每组测试数据的相应结果。

    完蛋了

    想的DP方程太复杂了,根本没法写

    完蛋惹

     

    这里大致就是f[i][j]表示前i个字符,已经有了j个划分(不是分割线)

    用aft[i]表示i往后,以i开头的单词最短到哪里

    这样统计i到j的单词个数只要找到i到j中aft小于等于j的就可以了

    这样首字母的问题,也很好的解决了

    然后这里j是到了第几个分块,而不是第几个分割线(我的,复杂)这样直接枚举前一个分块的末端就可以了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=207;
     8 const int INF=0x7f7f7f7f;
     9 int P,K,s,n,ans;
    10 char a[maxn],wrd[7][maxn];
    11 int len[7],aft[maxn],f[maxn][maxn],map[maxn][maxn];
    12 bool vis[maxn];
    13 int main(){
    14   //freopen("a.in","r",stdin);
    15   memset(f,-INF,sizeof(f));
    16   cin>>P>>K;memset(aft,INF,sizeof(aft));
    17   for(int i=1;i<=P;i++)
    18     for(int j=1;j<=20;j++)
    19       cin>>a[++n];
    20   cin>>s;
    21   for(int i=1;i<=s;i++){
    22     scanf("%s",wrd[i]+1);
    23     len[i]=strlen(wrd[i]+1);
    24   }
    25   for(int u=1;u<=n;u++){
    26     for(int i=1;i<=s;i++){
    27       int v=u+len[i]-1;bool flag=true;
    28       for(int k=u;k<=v;k++){
    29         if(a[k]!=wrd[i][k-u+1]) {
    30           flag=false;break;
    31         }
    32       }
    33       if(flag) aft[u]=min(aft[u],v);
    34     }
    35   }
    36   f[0][0]=0;
    37   for(int i=1;i<=n;i++){
    38     for(int j=i+1;j<=n;j++){
    39       for(int k=i;k<=j;k++){
    40         if(aft[k]<=j) map[i][j]++;
    41       }
    42     }
    43   }
    44   for(int i=1;i<=n;i++){
    45     for(int j=1;j<=K;j++){
    46       for(int k=0;k<i;k++){
    47         f[i][j]=max(f[i][j],f[k][j-1]+map[k+1][i]);
    48       }
    49     }
    50   }
    51   /*for(int i=1;i<=n;i++){
    52     for(int j=0;j<i;j++){
    53       for(int k=1;k<=K;k++)
    54         f[i][k]=max(f[i][k],f[j][k-1]+map[j+1][i]); 
    55     } 
    56   } */
    57   cout<<f[n][K]<<endl;
    58   return 0;
    59 } 

    真难过

    今天下午的状态太不应该了

  • 相关阅读:
    Linux关闭防火墙和selinux
    Linux内存VSS,RSS,PSS,USS解析
    JS 将有父子关系的数组转换成树形结构数据
    npm install报错类似于npm WARN tar ENOENT: no such file or directory, open '*** ode_modules.staging***
    react-native之文件上传下载
    Markdown语法简记
    MySQL运维开发
    股票投资
    数据仓库原理与实战
    python基础
  • 原文地址:https://www.cnblogs.com/lcan/p/9827058.html
Copyright © 2020-2023  润新知