Luogu_P1026 统计单词个数 DP+string

Luogu_P1026 统计单词个数

### DP+string

题目链接
题面是个什么玩意
选了this不能选th的原因是t被占用
所以只要避开第一个字母就行
字符串可以用string
string的substr(l,len)函数表示把l之后长度为len的字符拿出来
find(x)则是查询字符串x第一次出现的起始位置
那么这个题就比较简单了
先处理出一个数组\(sum[i][j]\)表示从\(i\)到\(j\)有多少字典串在原串上面出现了
因为第一个字母不能重叠,所以要\(j\)倒序更新
然后\(f[i][j]\)表示到\(i\)分为\(j\)段的价值
枚举更新就行了
\(f[i][j]=max(f[l][j-1]+sum[l+1][i])\)



代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,p,k,tot,f[210][210],sum[210][210];
string s,ch[10];
inline bool hac(int l,int r){
    string a=s.substr(l,r-l+1);
    for(int i=1;i<=n;i++) if(a.find(ch[i])==0) return 1;
    return 0;
}
int main()
{
    scanf("%d%d",&p,&k);s+='0';
    for(int i=1;i<=p;i++){
        string a;cin>>a;s+=a;
    }
    scanf("%d",&n);
    for(int i=1;i<=n;i++) cin>>ch[i];
    int len=s.length()-1;
    for(int i=1;i<=len;i++)
        for(int j=i;j>=1;j--){
            sum[j][i]=sum[j+1][i];
            if(hac(j,i)) sum[j][i]++;
        }
    for(int i=1;i<=len;i++) f[i][1]=sum[1][i];
    for(int i=1;i<=len;i++)
        for(int j=1;j<i&&j<=k;j++)
            for(int t=j;t<i;t++)
                f[i][j]=max(f[i][j],f[t][j-1]+sum[t+1][i]);
    printf("%d\n",f[len][k]);
    return 0;
}

原文地址:https://www.cnblogs.com/ChrisKKK/p/11633427.html

时间: 2025-01-11 14:42:00

Luogu_P1026 统计单词个数 DP+string的相关文章

P1026 统计单词个数 [dp]

P1026 统计单词个数 这道题看上去就是要用dp的样子.裸裸的dp题无误. 首先要把分开的字符串合成那个长度小于等于\(200\)的总字符串. 然后做个预处理,预处理出任意区间内的单词个数,设为\(sum[i][j]\). 有一个神奇的地方: 当选用一个单词之后,其第一个字母不能再用. 题解里面有这么一种解决方式: 倒序枚举\(j\)和\(i\).初始化\(sum[i][j] = sum[i + 1][j]\).如果子串中从一开始就存在单词,加1. 其实不怎么知道原理这种做法还刚好满足了上面的

NOIP2001 统计单词个数

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

P1026 统计单词个数——substr

P1026 统计单词个数 string 基本操作: substr(x,y) x是起始位置,y是长度: 返回的是这一段字符串: 先预处理sum[i][j],表示以i开头,最多的单词数: 从后往前寻找,保证开头没有被用过: sum[i][j]=sum[i+1][j]; 再找是否有新单词出现: s.find()==0说明找到单词以开头开始: 然后dp,f[i][j]表示以i结尾分j段的最大单词数: #include<cstdio> #include<string> #include<

codevs 1040 统计单词个数

1040 统计单词个数 2001年NOIP全国联赛提高组  题目等级 : 黄金 Gold 题目描述 Description 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠.当选用一个单词之后,其第一个字母不能再用.例如字符串this中可包含this和is,选用this之后就不能包含th)(管理员注:这里的不能再用指

kwic--Java统计单词个数并按照顺序输出

2016-07-02(随笔写作时间) 写了好久的程序了为了避免以后用到.......... 是一个统计单词个数,并按照个数从大到小输出的.输入文件名OK 了 单词是按照首字母排序的,,,里面用到映射等,,,注意重写比较函数,因为我们是要按值排序,而不是一般的按照键排序,,,,我们要输出的由多到少的个数,,,有个数是重复的 if (base.get(a) >=base.get(b)) { return -1; //注意 不要返回0 会删除重复 } 就起到了关键作用. 由于我们要按照个数多少排序,所

P1026 统计单词个数

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

NOIP200107统计单词个数

NOIP200107统计单词个数 难度级别: A: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠,但不能选出两个单词而它们的开始位置相同). 单词在给出的一个不超过6个单词的字典中.要求输出最大

1040 统计单词个数

1040 统计单词个数 2001年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠.当选用一个单词之后,其第一个字母不能再用.例如字符串this中可包含this和is,选用

Linux驱动程序:统计单词个数

本例为Android升读探索(卷1):HAL与驱动开发 一书中附带的示例程序.现粘贴出来,以便查阅. 终端操作,可能用到的命令: insmond word_count.ko lsmod | grep word_count 查看驱动是否安装成功 rmmod word_count dmesg | grep word_cout | tail -n 2 查看有linux驱动输出的日志信息 cat /var/log/syslong | grep word_count | tail -n 2 modinfo