bzoj 2121 字符串游戏
2015-11-16 10:40
316 查看
BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删除,如果删除,则将删除后L分裂成的左右两部分合并。举个例子,L='abcdefg' , S={'de'},如果BX选择将'de'从L中删去,则删后的L='abcfg'。现在BX可以进行任意多次操作(删的次数,顺序都随意),他想知道最后L串的最短长度是多少。
f[i][j][k][p]表示i到j是否可以表示第k个字符串的前p个字符。c[i][j]表示i到j是否可以全部删去。有两种转移‘f[j-1][k][p-1]&&st[k][p]==S[j]f[d][k][p]&&c[d+1][j]类似区间dp的东西可以采用固定一端,枚举另一端的方法
f[i][j][k][p]表示i到j是否可以表示第k个字符串的前p个字符。c[i][j]表示i到j是否可以全部删去。有两种转移‘f[j-1][k][p-1]&&st[k][p]==S[j]f[d][k][p]&&c[d+1][j]类似区间dp的东西可以采用固定一端,枚举另一端的方法
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define ll long long #define inf 1e9 #define eps 1e-10 #define md #define N using namespace std; bool f[170][35][25],c[170][170]; int dp[170],len[35]; char S[170],st[35][25]; int main() { scanf("%s",S+1); int lth=strlen(S+1); int n; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%s",st[i]+1); len[i]=strlen(st[i]+1); } for (int i=lth;i;i--) { memset(f,0,sizeof(f)); for (int k=1;k<=n;k++) f[i-1][k][0]=1; for (int j=i;j<=lth;j++) { for (int k=1;k<=n;k++) for (int p=1;p<=len[k];p++) f[j][k][p]|=(f[j-1][k][p-1]&&st[k][p]==S[j]); for (int d=i;d<=j;d++) if (c[d+1][j]) { for (int k=1;k<=n;k++) for (int p=1;p<=len[k];p++) f[j][k][p]|=f[d][k][p]; } } for (int j=i;j<=lth;j++) for (int k=1;k<=n;k++) c[i][j]|=f[j][k][len[k]]; } for (int i=1;i<=lth;i++) { dp[i]=dp[i-1]+1; for (int j=1;j<=i;j++) if (c[j][i]) dp[i]=min(dp[i],dp[j-1]); } printf("%d\n",dp[lth]); return 0; }
相关文章推荐
- bzoj 1049 数字序列
- bzoj 2669 局部极小值
- bzoj 3743 kmap
- dp专题训练
- bzoj 1060 时态同步 水题?神题?
- 练贪心!贪心!贪心!
- bzoj 3175 攻击装置 | 二分图最大独立集
- 图解javascript this指向什么?
- 远程控制电脑
- Linux Basics command
- java http 请求方法
- .ajax设置成同步的应用场景
- java泛型编程
- linux下apache2两种工作模式及两者切换
- bzoj 3032 七夕祭 | 中位数
- bzoj 2594 水管局长 | LCT | 最小生成树
- bzoj 3706 反色刷 | 一笔画
- bzoj 3108 图的逆变换
- bzoj 2660 最多的方案 | 斐波那契数列
- bzoj 1187 神奇的游乐园 | 插头dp