• NOIP 统计单词个数


    描述

    给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串this中可包含this和is,选用this之后就不能包含th)。

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

    要求输出最大的个数。

    格式

    输入格式

    第一行有二个正整数(p,k)
    p表示字串的行数;
    k表示分为k个部分。

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

    再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)
    接下来的s行,每行均有一个单词。

    输出格式

    输出一个整数,即最大的个数

    样例1

    样例输入1[复制]

     
    1 3
    thisisabookyouareaoh
    4
    is
    a
    ok
    sab

    样例输出1[复制]

     
    7

    限制

    每个测试点1s

    来源

    NOIP2001第三题

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstring>
     7 using namespace std;
     8 char T[50000],ss[50000];//T是目标串  
     9 char P[10][1000];//P是模式串  
    10 int sum[1000][1000];//sum[i][j]表示T串中 i 到  j 之间单词个数  
    11 int f[1000][1000];//f[i][j]表示吧前 i个字符分成 j部分的最优值 
    12 int n,k,m,tot;
    13 bool jud(int l,int r,int num){
    14     if(strlen(P[num]+1)>r-l+1){//要匹配长度比整个串还长 
    15         return false;
    16     }
    17     int now=1;
    18     for(;;){
    19         if(T[l]!=P[num][now])
    20             return false;
    21         else if(now==strlen(P[num]+1))
    22             return true;
    23         l++,now++;
    24     }
    25 }
    26 int main(){
    27     
    28     scanf("%d%d",&n,&k);
    29     tot=20*n;
    30     
    31     for(int i=1;i<=n;i++){
    32         scanf("%s",ss+1);
    33         for(int j=1;j<=20;j++){
    34             int now=20*(i-1)+j;
    35             T[now]=ss[j];
    36         }
    37     }
    38     
    39     scanf("%d",&m);
    40     for(int i=1;i<=m;i++){
    41         scanf("%s",P[i]+1);
    42     }
    43     for(int i=tot;i>=1;i--){//
    44         for(int j=i;j>=1;j--){//
    45             for(int v=1;v<=m;v++){//从 i到 j 有字符串P[v] 
    46                 if(jud(j,i,v)==true){
    47                     sum[j][i]=sum[j+1][i]+1;
    48                     break;
    49                 }
    50                 sum[j][i]=sum[j+1][i];
    51             }
    52         }
    53     }
    54     
    55     for(int i=1;i<=tot;i++) f[i][1]=sum[1][i];
    56     if(k==0){
    57         cout<<sum[1][tot];
    58         return 0;
    59     } 
    60     
    61     for(int i=1;i<=tot;i++){//前i个字母 
    62         for(int j=1;j<=k&&j<=i;j++){//用j次划分,划分份数不会超过 k 和 i 
    63             for(int t=k;t<i;t++){//在t处断一次 
    64                 f[i][j]=max(f[i][j],f[t][j-1]+sum[t+1][i]);
    65             }
    66         }
    67     }
    68     cout<<f[tot][k]<<endl;
    69     return 0;
    70 }
  • 相关阅读:
    __name__在调用时的区别
    Python内置模块--os模块的使用
    查询mysql 表的元数据信息
    nfs服务搭建
    jvm参数设置
    spring boot 集成 beetl
    spring boot 集成 swagger2 四部曲
    JavaScript中的this关键字
    jQuery 基础事件
    jQuery 表单选择器
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/4771266.html
Copyright © 2020-2023  润新知