Description

BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对
于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删除,如果删除,则将删除后L分裂成的左右
两部分合并。举个例子,L='abcdefg' , S={'de'},如果BX选择将'de'从L中删去,则删后的L='abcfg'。现在BX可
以进行任意多次操作(删的次数,顺序都随意),他想知道最后L串的最短长度是多少。

Input

输入的第一行包含一个字符串,表示L。
第二行包含一个数字n,表示集合S中元素个数。
以下n行,每行一个字符串,表示S中的一个元素。
输入字符串都只包含小写字母。

Output

输出一个整数,表示L的最短长度。

比较神仙的动态规划.

定义 $g[l][r][i][j]$ 表示是否可以将区间 $[l,r]$ 删至只剩下第 $i$ 个串的前 $j$ 位 $,$ $f[l][r]$ 表示是否可以将 $[l,r]$ 这个区间全部删除掉,而 $h[i]$ 表示对 $1$~$i$ 操作后保留的最短长度.
如果能知道 $f$,则可得转移 $h[i]=min(h[i],h[j]),f[j+1][i]=1$.
现在关键在于如何求出 $f$ 数组.
按照区间 $dp$ 的方式依次枚举区间长度.
令当前枚举的区间长度为 $len,$ 则:
$g[l][r-1][i][j-1]\Rightarrow g[l][r][i][j],$ 或者 $f[l][k]\&\&g[k+1][r][i][j]$.
转移完当前区间的 $g$ 数组后,就可以依次判断是否可以更新 $f$ 数组了.
这种区间 $dp$ 都挺巧妙的.

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #define N 160
  5. #define setIO(s) freopen(s".in", "r" , stdin)
  6. using namespace std;
  7. int n,m;
  8. char L[N],S[32][N];
  9. int length[N],g[N][N][32][22],f[N][N],h[N];
  10. int main()
  11. {
  12. int i,j,len;
  13. // setIO("input");
  14. scanf("%s%d",L+1,&m),n=strlen(L+1);
  15. for(i=1;i<=m;++i)
  16. {
  17. scanf("%s",S[i]+1),length[i]=strlen(S[i]+1);
  18. for(j=1;j<=n;++j)
  19. {
  20. if(L[j]==S[i][1])
  21. {
  22. g[j][j][i][1]=1;
  23. if(length[i]==1) f[j][j]=1;
  24. }
  25. }
  26. }
  27. for(len=2;len<=n;++len)
  28. {
  29. int l,r,k;
  30. for(l=1;(r=l+len-1)<=n;++l)
  31. {
  32. for(i=1;i<=m;++i)
  33. {
  34. for(j=1;j<=length[i];++j)
  35. if(S[i][j]==L[r])
  36. g[l][r][i][j]|=g[l][r-1][i][j-1];
  37. }
  38. for(i=1;i<=m;++i)
  39. {
  40. for(j=1;j<=length[i];++j)
  41. for(k=l;k<r;++k)
  42. if(g[l][k][i][j]&&f[k+1][r]) g[l][r][i][j]=1;
  43. // g[l][r][i][j]|=(g[l][k][i][j] && f[k+1][r]);
  44. }
  45. for(i=1;i<=m;++i) f[l][r]|=g[l][r][i][length[i]];
  46. }
  47. }
  48. for(i=1;i<=n;++i)
  49. {
  50. h[i]=h[i-1]+1;
  51. for(j=1;j<=i;++j) if(f[j][i]) h[i]=min(h[i], h[j-1]);
  52. }
  53. printf("%d\n",h[n]);
  54. return 0;
  55. }

  

BZOJ 2121: 字符串游戏 区间DP + 思维的更多相关文章

  1. BZOJ#2121. 字符串游戏 [区间dp]

    // powered by c++11 // by Isaunoya #include<bits/stdc++.h> #define rep(i , x , y) for(register ...

  2. 【bzoj2121】字符串游戏 区间dp

    题目描述 给你一个字符串L和一个字符串集合S,如果S的某个子串在S集合中,那么可以将其删去,剩余的部分拼到一起成为新的L串.问:最后剩下的串长度的最小值. 输入 输入的第一行包含一个字符串,表示L. ...

  3. BZOJ 1090 字符串折叠(区间DP)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1090 题意:字符串AAAAAAAAAABABABCCD的最短折叠为9(A)3(AB)CC ...

  4. BZOJ2121: 字符串游戏(DP)(字符串删单词,求最多可以删去多少)

    2121: 字符串游戏 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 672  Solved: 376[Submit][Status][Discuss ...

  5. BZOJ 1260&UVa 4394 区间DP

    题意: 给一段字符串成段染色,问染成目标串最少次数. SOL: 区间DP... DP[i][j]表示从i染到j最小代价 转移:dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k ...

  6. 【BZOJ-1090】字符串折叠 区间DP + Hash

    1090: [SCOI2003]字符串折叠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1127  Solved: 737[Submit][Stat ...

  7. 洛谷P4302 [SCOI2003]字符串折叠(区间dp)

    题意 题目链接 Sol 裸的区间dp. 转移的时候枚举一下断点.然后判断一下区间内的字符串是否循环即可 `cpp #include<bits/stdc++.h> #define Pair ...

  8. BZOJ 1055 玩具取名(区间DP)

    很显然的区间DP,定义dp[i][j][k], 如果dp[i][j][k]=1表示字符串[i,j]可以组成k字符. # include <cstdio> # include <cst ...

  9. bzoj 1068 [SCOI2007]压缩 区间dp

    [SCOI2007]压缩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 1644  Solved: 1042[Submit][Status][Discu ...

随机推荐

  1. 【神经网络与深度学习】【python开发】caffe-windows使能python接口使用draw_net.py绘制网络结构图过程

    [神经网络与深度学习][python开发]caffe-windows使能python接口使用draw_net.py绘制网络结构图过程 标签:[神经网络与深度学习] [python开发] 主要是想用py ...

  2. for循环实现九九乘法表

    <!--for循环实现九九乘法表--> <table border="> <tbody> {% for x in range(1,10) %} <t ...

  3. Win10无法安装.net framework 3.5出错提示无法安装以下功能该怎么办?

    在Windows操作系统中,.NET Framewor对今天应用程序的成功提供了的安全解决方案,它能强化两个安全模型间的平衡.在提供对资源的访问,以便以完成有用的工作,对应用程序的安全性作细致的控制以 ...

  4. Java学习开发第二阶段总结

    第二阶段的学习总结: 在这次学习中虽说任务量是比上次提升了不少.但大部分的内容都于C语言相同或者类似.学习起来相对来说很轻松.但也在这次学习中学到新的知识 ①Jshell 在cmd中运行Jshell脚 ...

  5. Fescar使用(资料)

    fescar源码走读1:业务调用方 https://zhuanlan.zhihu.com/p/54659540   fescar源码走读2:fescar服务端 https://zhuanlan.zhi ...

  6. 高性能异步分布式事务TCC框架(资料汇总)

    https://github.com/yu199195/hmily tcc源码解析系列(一)之项目结构 https://yu199195.github.io/2017/10/11/TCC/tcc-on ...

  7. eclipse中svn的使用

    1.在eclipse中添加SVN插件或者说直接利用eclipse软件中的help-install项进行网站在线下载也可 2.安装好SVN之后, 2.1.从SVN检出项目到本地 右击鼠标-选import ...

  8. 阿里云安装filezilla

    1.连接服务器 ssh 或者 远程连接 到服务器: 2.安装相应软件 安装EPEL,EPEL是yum的一个软件源,里面包含了许多基本源里没有的软件: yum -y install epel-relea ...

  9. Oracle常用启停命令

    一.监听启停 Oracle监听的启动.停止和状态查看 Oracle监听启动: lsnrctl start Oracle监听停止: lsnrctl stop Oracle监听状态 lsnrctl sta ...

  10. Layui关闭弹出层并刷新父窗口

    先确保已经引入layui和jquery 再确保初始化layer弹出层 <script> layui.use(['form', 'layer'], function() { var form ...