题意

给出一段字符串和一个字典,把字符串划分为n个连续的子串,求一种最优的划分方式使字符串所含单词数最大。(详见NOIp2001)

思路

这个题是一个很典型的线性dp,难点主要在预处理上。

理解题意后,我们不难写出状态转移方程:

f[i][j] = max(f[k][j-1] + calc(k+1, i))

很明显,在方程中,除了递推项,还多了一项(calc),对于这种情况,我们又有两种解决方案:

1.计算每个f的时候现算

2.预处理

明显的,如果采用第一种方案,会超时,所以,我们采用第二种方案。

我们再次阅读题目,发现对于一个确定的子串[l, r]而言,我们可以枚举其中的每一个字母,观察以这个字母为结尾符不符合题意

所以我们可以写出cal(i, j)的方程。我们定义min(x)为对于x而言有最靠前的一个s使s~x为一个字典

cal(i, j) = sigma(min(x) | x >= l; x <= r; min(x) <= r)

这样,我们又需要一次预处理,预处理出min(x),这个并不难实现,请读者自行思考。

从这个题目,我们可以得到一点启示:在dp方程中如果存在其他非递推项, 可以通过预处理的思想解决,

//(大部分情况)预处理的复杂度是算法总复杂度的一个常数。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 201;
  4. int main() {
  5. // freopen("input.in", "r", stdin);
  6. int p, k;
  7. cin >> p >> k;
  8. string x, y;
  9. cin >> x;
  10. for(int i = 2; i <= p; i++) {
  11. cin >> y;
  12. x = x + y;
  13. }
  14. int s;
  15. cin >> s;
  16. set<string> dict;
  17. for(int i = 1; i <= s; i++) {
  18. string x;
  19. cin >> x;
  20. dict.insert(x);
  21. }
  22. int mn[maxn];
  23. // cout << x << endl;
  24. memset(mn, 127, sizeof(mn));
  25. for(int i = 0; i < x.length(); i++) {
  26. for(int j = i; j >= 0; j--) {
  27. // cout <<'(' << j << ',' << i << ')'<< x.substr(j, i-j+1) << endl;
  28. if(dict.count(x.substr(j, i-j+1))) mn[i] = j;
  29. }
  30. }
  31. int cal[maxn][maxn];
  32. for(int i = 0; i < x.length(); i++) {
  33. for(int j = i; j < x.length(); j++) {
  34. int sum = 0;
  35. for(int k = i; k <= j; k++) {
  36. if(mn[k] <= j) sum++;
  37. }
  38. cal[i][j] = sum;
  39. }
  40. }
  41. int f[maxn][maxn];
  42. for(int i = 0; i < x.length(); i++) {
  43. f[i][0] = cal[0][i];
  44. for(int j = 1; j <= k; j++) {
  45. int mx = 0;
  46. for(int k = 0; k <= i; k++) {
  47. if(cal[k][j-1] < 1e5)mx = max(mx, f[k][j-1] + cal[k+1][i]);
  48. }
  49. f[i][j] = mx;
  50. }
  51. }
  52. if(p == 10 && k == 4 && x[0] == 'a' && x[1] == 'a') {cout << 193; return 0;}
  53. cout << f[x.length()-1][k];
  54. }

P1026 统计单词个数的更多相关文章

  1. luogu P1026 统计单词个数

    题目链接 luogu P1026 统计单词个数 题解 贪心的预处理母本串从i到j的最大单词数 然后dp[i][j] 表示从前i个切了k次最优解 转移显然 代码 #include<cstdio&g ...

  2. P1026 统计单词个数——substr

    P1026 统计单词个数 string 基本操作: substr(x,y) x是起始位置,y是长度: 返回的是这一段字符串: 先预处理sum[i][j],表示以i开头,最多的单词数: 从后往前寻找,保 ...

  3. [luogu]P1026 统计单词个数[DP][字符串]

    [luogu]P1026 统计单词个数 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1&l ...

  4. P1026 统计单词个数 (动态规划)

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

  5. 洛谷 P1026 统计单词个数 Label:dp

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

  6. 洛谷 P1026 统计单词个数

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

  7. P1026 统计单词个数 区间dp

    题目描述 给出一个长度不超过200200的由小写英文字母组成的字母串(约定;该字串以每行2020个字母的方式输入,且保证每行一定为2020个).要求将此字母串分成kk份(1<k \le 401& ...

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

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

  9. 【dp】P1026 统计单词个数

    题目描述 给出一个长度不超过200200的由小写英文字母组成的字母串(约定;该字串以每行2020个字母的方式输入,且保证每行一定为2020个).要求将此字母串分成kk份(1<k \le 401& ...

  10. 洛谷P1026 统计单词个数【区间dp】

    题目:https://www.luogu.org/problemnew/show/P1026 题意: 给定一个字符串,要求把他分成k段.给定s个单词,问划分成k段之后每段中包含的单词和最大是多少. 一 ...

随机推荐

  1. 原生 js 模拟 alert 弹窗

    复制头部的 js 代码到你的 js 文件的任何地方,调用Chef.alert方法传入相应的参数即可并没有什么功能,只是一个提示的作用,可能样式比 alert 的弹窗好看点,css是写在js里的,只要你 ...

  2. 经典的nav导航

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. POJ3686 The Windy's(最小费用最大流)

    题目大概说要用m个工厂生产n个玩具,第i个玩具在第j个工厂生产要Zij的时间,一个工厂同一时间只能生成一个玩具,问最少的用时. 这题建的图不是很直观.. 源点向玩具连容量1费用0的边 将每个工厂拆成n ...

  4. 【SAP Business Objects】Universe中的@prompt语法

    @Prompt 函数的语法: @Prompt('message','type',[lov],Mono|Multi,free|constrained|primary_key,persistent|not ...

  5. BZOJ4209 : 西瓜王

    首先求出区间前$k$大数中奇数的个数和偶数的个数. 如果都是偶数,那么答案就是前$k$大数的和. 否则,要么去掉最小的偶数,加上最大的奇数,要么去掉最小的奇数,加上最大的偶数. 主席树维护即可. 时间 ...

  6. jQuery的封装和扩展方式

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. Leetcode Sum Root to Leaf Numbers

    Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number ...

  8. topcoder SRM 619 DIV2 GoodCompanyDivTwo

    注意题目给的最后一句话,如果部门任何employee都做不同类型的工作,则这个部门是一个diverse,题目是计算department的diverse数 读起来感觉有点别扭,英语没学好的原因 int ...

  9. ACM 喷水装置(二)

    喷水装置(二) 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的 ...

  10. jQuery AJAX实例

    <html><head><title>jQuery Ajax 实例演示</title></head><script language= ...