[NOIP2001] 提高组 洛谷P1026 统计单词个数

题目描述

给出一个长度不超过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 3
thisisabookyouareaoh
4
is
a
ok
sab

输出样例#1:

7

说明

this/isabookyoua/reaoh

两次DP,第一次预处理出区间[i][j]内的单词个数,第二次处理分段最优解。

 1 /*By SilverN*/
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<algorithm>
 7 #define LL long long
 8 using namespace std;
 9 int p,K;
10 int len;
11 int n;
12 char s[240];
13 char a[240][240];
14 bool fd(int st,int ed){
15     for(int i=1;i<=n;i++){
16         char *p=strstr(s+st,a[i]+1);
17         if(p==NULL)continue;
18         if(p-&s[st]==0 && strlen(a[i]+1)<=ed-st+1)
19             return 1;
20     }
21     return 0;
22 }
23 int f[240][240];
24 int cnt[240][240];
25 int dp(){
26     int i,j,k;
27     for(i=1;i<=K;i++)f[i][i]=f[i-1][i-1]+cnt[i][i];
28     for(i=1;i<=len;i++)f[i][1]=cnt[1][i];
29     for(i=1;i<=len;i++)
30      for(j=1;j<i && j<=K;j++)
31       for(k=j;k<i;k++){
32           f[i][j]=max(f[i][j],f[k][j-1]+cnt[k+1][i]);
33       }
34     return f[len][K];
35 }
36 int main(){
37     scanf("%d%d",&p,&K);
38     int i,j;
39     char tmp[24];
40     for(i=1;i<=p;++i){
41         scanf("%s",tmp);
42         strcat(s+1,tmp);
43     }
44     len=20*p;
45     scanf("%d",&n);
46     for(i=1;i<=n;i++){scanf("%s",a[i]+1);}
47     for(i=len;i;--i){
48         for(j=i;j;--j){
49             if(fd(j,i))    cnt[j][i]=cnt[j+1][i]+1;
50             else cnt[j][i]=cnt[j+1][i];
51         }
52     }
53     cout<<dp()<<endl;
54     return 0;
55 }
时间: 2024-10-13 11:42:00

[NOIP2001] 提高组 洛谷P1026 统计单词个数的相关文章

洛谷 P1026 统计单词个数 区间DP

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

[NOIP2001] 提高组 洛谷P1027 Car的旅行路线

题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个 矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线, 所有航线单位里程的价格均为t. 图例(从上而下) 机场 高速铁路 飞机航线 注意:图中并没有 标出所有的铁路与航线. 那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教. 找出一条从城市A到

[NOIP2001] 提高组 洛谷P1025 数的划分

题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法. 输入输出格式 输入格式: n,k (6<n<=200,2<=k<=6) 输出格式: 一个整数,即不同的分法. 输入输出样例 输入样例#1: 7 3 输出样例#1: 4 说明 四种分法为:1,1,5;1,2,4;1,3,3;2,2,3; 暴搜. 可以加一点剪枝,比如说当剩余数不够均分成剩余

[NOIP2001] 提高组 洛谷P1024 一元三次方程求解

题目描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位. 提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定有一个根. 输入输出格式 输入格式: 一行,4个实数A,B,C,D. 输

P1026 统计单词个数

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

luogu P1026 统计单词个数

题目链接 luogu P1026 统计单词个数 题解 贪心的预处理母本串从i到j的最大单词数 然后dp[i][j] 表示从前i个切了k次最优解 转移显然 代码 #include<cstdio> #include<algorithm> #include<cstring> const int maxn = 507; char a[maxn]; char s[maxn],t[maxn]; int dp[maxn][55]; int n,k,q; int num[maxn][m

P1026 统计单词个数 [dp]

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

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<

[NOIP2000] 提高组 洛谷P1019 单词接龙

题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单