首先如果我们能处理出来i,j段能不能消掉,这样就可以直接dp转移了,设w[i]为前i为最少剩下多少,那么w[i]=w[j-1] (flag[j][i])。

  现在我们来求flag[i][j],首先我们可以把字符串组建立trie然后处理在串L中从left位置开始的所有的flag,那么我们可以在trie上一直往下走,每到一个标记的点就将当前的flag[left][right]设为1,那么这样可以处理出连续可以消掉的字符串,然后就处理对于类似L为abcde,字符串组为ade,bc这样可以先消一个,然后再消的情况,这样我们可以发现,如果对于当前的left,right存在flag[i][right]=1,那么就是这样的情况,那么我们直接递归处理left,i就好了,但是我们发现这里的flag[i][right]的i是大于left的,所以我们在处理以某个为开头的所有的flag的时候需要倒序处理。

  有一个优化,在同一个left时,我们在处理flag的时候有两种拓展情况,所以对于每一个i我们记录一个vis[i][j],表示在当前的left,i节点,right为j的情况是否访问过,这样有访问的情况return就好了。

  反思:开始没加优化,挺快就a了,后来加了优化之后,因为我用的指针存的trie,所以vis数组中节点的编号需要对于每个指针都存一个编号,但是这个编号不知道怎么回事儿,一申请就re,后面的按照不加优化的写,只是在node那在cnt之前申请一个num就会re,在cnt之后申请就没问题,调了半个上午也不知道怎么回事儿= =,原来一直是这么写的啊。

  反思2:后来发现是return的条件为right>=len,写成right>len了,这样就有了未定义行为。

/**************************************************************Problem: 2121User: BLADEVILLanguage: C++Result: AcceptedTime:132 msMemory:158900 kb
****************************************************************///By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 200
#define maxm 1010using namespace std;struct node{int cnt,num; node *child[30];node(){ cnt=num=0;memset(child,0,sizeof child);}
}nodepool[maxm],*totnode,*rot;char s[maxn];
int flag[maxn][maxn],vis[maxn][maxm][maxn],w[maxn];
int n,len;void build_trie(){int j=1;totnode=nodepool; rot=totnode++;scanf("%d",&n);char ch[maxn];while (n--) {scanf("%s",ch);int len=strlen(ch);node *t=rot;for (int i=0;i<len;i++) {if (!t->child[ch[i]-'a']) t->child[ch[i]-'a']=totnode++,t->child[ch[i]-'a']->num=j++;t=t->child[ch[i]-'a'];}t->cnt=1;}
}void make(node *rot,int left,int right) {//printf("%d ",rot->num);if (rot->cnt) flag[left][right-1]=1;if (vis[left][rot->num][right]) return ;if (right>=len) return ;vis[left][rot->num][right]=1;if (rot->child[s[right]-'a']) make(rot->child[s[right]-'a'],left,right+1);for (int i=right;i<len;i++) if (flag[right][i]) make(rot,left,i+1);
}int main() {scanf("%s",s); len=strlen(s);build_trie();for (int i=len-1;i>=0;i--) make(rot,i,i);/*for (int i=0;i<len;i++) {for (int j=0;j<len;j++) printf("%d ",flag[i][j]);printf("\n");}*/w[0]=0;for (int i=0;i<len;i++) {w[i+1]=w[i]+1;for (int j=0;j<=i;j++) if (flag[j][i]) w[i+1]=min(w[i+1],w[j]);//printf("%d ",w[i]);
    }//printf("\n");printf("%d\n",w[len]);return 0;
}

转载于:https://www.cnblogs.com/BLADEVIL/p/3591127.html

bzoj 2121 DP相关推荐

  1. BZOJ 2423 DP

    BZOJ 2423 - DP 第一问是经典DP,直接做就可以了(设\(f[i][j]\)为\(X\)串考虑到\(i\),\(Y\)串考虑到\(j\),且不强制选\(i\)和\(j\)的方案数).然后第 ...

  2. bzoj 2121 字符串游戏(字符串dp)

    Description BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删除 ...

  3. bzoj 1084 DP

    首先对于m==1的情况非常容易处理(其实这儿因为边界我错了好久...),直接DP就好了,设f[i][k]为这个矩阵前i个选k个矩阵的最大和,那么f[i][k]=max(f[j][k-1]+sum[j+ ...

  4. BZOJ 2431 DP

    题意:求逆序对数量为k的长度为n的排列的个数 SOL: 显然我们可以对最后一位数字进行讨论,判断其已经产生多少逆序对数量,然后对于前n-1位同样考虑---->每一个长度的排列我们都可以看做是相同 ...

  5. bzoj 2121 字符串游戏

    BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删除,如果删除,则将删除后L ...

  6. BZOJ 2121: 字符串游戏

    这道题太腻害辣..我太菜了想不出来.. 看了题解之后 还是有点懵.. 你们可以去看看这位大神的 点击打开链接 首先 我们定义状态 f[i][j][k][l]表示字符串区间[i,j]匹配到第k个小串的第 ...

  7. BZOJ 1786 DP

    思路: 肯定从小往大填合适了 f[i][j]表示第i个数是j的最少逆序对数 f[i][j]=min(f[i-1][k]+cost,f[i][j]) 优化一下成O(nk)就好啦~ (不优化也可以过的-) ...

  8. bzoj 2786 DP

    我们可以将=左右的两个数看成一个块,块内无顺序要求,把<分隔的看成两个块,那么我们设w[i][j]代表将i个元素分成j个块的方案数,那么显然w[i][j]=w[i-1][j]*j+w[i-1][ ...

  9. 5.4 ~ 5.6 刷题记录

    bzoj 1096 斜率优化水题,( 闭着眼做) /**************************************************************Problem: 109 ...

最新文章

  1. 计算机背小学英语吗,小学英语课本点读电脑版
  2. SVN 常用命令笔记
  3. 【Maven学习】Maven打包生成包含所有依赖的jar包
  4. LintCode:尾部的零
  5. 跟对人,走对路,做对事!
  6. visio2010 java类图_UML图及Visio 2010使用总结
  7. Ae 效果快速参考:3D 通道
  8. java 堆栈大小设置_如何增加Java堆栈大小?
  9. vue 下载文件 前后端代码亲测有效
  10. matlab清除坐标轴,matlab 使用技巧之设置坐标轴
  11. jhin 不在 sudoers 文件中。此事将被报告。
  12. 心电图心电轴怎么计算_心电图QRS电轴角度简易直读法
  13. 飞凌国产芯片系列经验分享|A40i开发板应用笔记-PWM 的应用
  14. 有一个姑娘,我无法忘记她
  15. 配置数据源失败:未指定“url”属性,无法配置嵌入的数据源。
  16. 淘宝总裁蒋凡:今年双11淘宝推荐流量超过了搜索流量
  17. SequenceToSequence
  18. lc用U盘更新固件_普通U盘和固态U盘相差多少?用下aigo固态U盘就知道了
  19. 用Python进行身份证号校验
  20. iOS - CodeReview 代码评审

热门文章

  1. matlab的try函数,matlab – 是否可以在没有try块的情况下测试函数句柄?
  2. rust队友开挂_腐蚀RUST开挂玩家识别方法 如何识别玩家开挂
  3. mysql从盘延迟_Mysql-主从延迟解决方法
  4. 文本界面安装linux 7,安装 CentOS7 后必做的事 [最小化、文本界面]
  5. java url特殊字符转义字符_URL中包含有特殊字符,进行转义
  6. php按文章评论数排序,zblog获取分类文章排序按指定的时间排序、评论数量排序、浏览数量排序...
  7. 跨域会报40几_总结一下跨域的几种情况
  8. mysql mos login_MySQL 中常用的函数
  9. 1101: 逆序数字(函数专题)
  10. poj1273Drainage Ditches