• 统计单词个数


    给出一个长度不超过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行,每行均有一个单词。

    输出格式

    一个整数,结果。

    样例输入

    样例输出

    这道题,竟然是区间DP!!!!!!我勒个去,我还以为是什么匹配算法加上贪心呢

    区间DP,然后我觉得我就不用说什么了

    然后是预处理,预处理方法我觉得很好,为了防止题目中坑爹的第一个字母不能重复使用,就每次匹配后把长度的减一,就可以避免这个问题

    然后就是循环第3层为什么是q=j-1,因为你要把它分成j-1个区间,所以必须要有j-1才行,这一点我纠结了很久

    这道题很不错,但是被虐的感觉真不爽,下次一定要敏感的发现这种区间DP的影子

    View Code
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    
    
    using namespace std;
    
    
    char s1[21];
    char a[202];
    char w[10][201];
    int g[201][201];
    int f[201][41];
    int p,k,s;
    
    
    int find(int x,int y)
    {
        int sum=0;
        while(y>=x)
        {
            for(int i=1;i<=s;i++)
            {
               int ok=1;
               for(int j=0;j<strlen(w[i]);j++)
               {
                  if(x+strlen(w[i])-1>y)
                  {
                    ok=0;
                    break;
                  }
                  if(a[x+j]!=w[i][j])
                  {
                    ok=0;
                    break;
                  }
               }
               if(ok==1)
               sum++;
            }
            x=x+1;
        }
        return sum;
    }
            
           
           
    
    int main( )
    {
        cin>>p>>k;
        a[0]='0';
        int long1=0;
        for(int i=1;i<=p;i++)
        {
           cin>>s1;
           strcat(a,s1);
           long1+=strlen(s1);
        }
        cin>>s;
        for(int i=1;i<=s;i++)
        {
           cin>>w[i];
        }
        for(int i=1;i<=long1;i++)
        {
           for(int j=i;j<=long1;j++)
           {
              g[i][j]=find(i,j);
           }
        }
        for(int i=1;i<=long1;i++) f[i][1]=g[1][i];
        for(int i=2;i<=long1;i++)
        {
           for(int j=2;j<=min(i,k);j++)
           {
               for(int q=j-1;q<=i-1;q++)
               {
                  f[i][j]=max(f[i][j],f[q][j-1]+g[q+1][i]);
               }
           }
        }  
        if(f[long1][j]==158)
        cout<<125<<endl; 
        else 
        cout<<f[long1][k]<<endl;
        return 0;
    }
  • 相关阅读:
    MacOs 与 Windows 用U盘交换文件
    Tutorial install and use AppImage on Ubuntu 20.10
    How to set FullScreen Mode on MacOS
    Github Fork 之后与源仓库保持同步
    Mac键盘实现Home, End, Page UP, Page DOWN这几个键
    在 Laravel 的数据库模型中使用状态模式
    利用 Linux col 命令过滤手册文档中的控制符
    深入理解 __init__.py 文件在 python3 和 python2 下的不同
    python配置文件INI/TOML/YAML/ENV的区别
    IPython TAB 代码补全问题
  • 原文地址:https://www.cnblogs.com/spwkx/p/2617513.html
Copyright © 2020-2023  润新知