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$ 都挺巧妙的.

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 160
#define setIO(s) freopen(s".in", "r" , stdin)
using namespace std;
int n,m;
char L[N],S[32][N];
int length[N],g[N][N][32][22],f[N][N],h[N];
int main()
{
int i,j,len;
// setIO("input");
scanf("%s%d",L+1,&m),n=strlen(L+1);
for(i=1;i<=m;++i)
{
scanf("%s",S[i]+1),length[i]=strlen(S[i]+1);
for(j=1;j<=n;++j)
{
if(L[j]==S[i][1])
{
g[j][j][i][1]=1;
if(length[i]==1) f[j][j]=1;
}
}
}
for(len=2;len<=n;++len)
{
int l,r,k;
for(l=1;(r=l+len-1)<=n;++l)
{
for(i=1;i<=m;++i)
{
for(j=1;j<=length[i];++j)
if(S[i][j]==L[r])
g[l][r][i][j]|=g[l][r-1][i][j-1];
}
for(i=1;i<=m;++i)
{
for(j=1;j<=length[i];++j)
for(k=l;k<r;++k)
if(g[l][k][i][j]&&f[k+1][r]) g[l][r][i][j]=1;
// g[l][r][i][j]|=(g[l][k][i][j] && f[k+1][r]);
}
for(i=1;i<=m;++i) f[l][r]|=g[l][r][i][length[i]];
}
}
for(i=1;i<=n;++i)
{
h[i]=h[i-1]+1;
for(j=1;j<=i;++j) if(f[j][i]) h[i]=min(h[i], h[j-1]);
}
printf("%d\n",h[n]);
return 0;
}

  

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. selenium学习-ActionChains方法列表

    ActionChains方法列表 click(on_element=None) ——单击鼠标左键 click_and_hold(on_element=None) ——点击鼠标左键,不松开 contex ...

  2. python 并发编程 多进程 生产者消费者模型介绍

    一 生产者消费者模型介绍 为什么要使用生产者消费者模型 生产者指的是生产数据的任务,消费者指的是处理数据的任务, 生产数据目的,是为了给消费者处理. 在并发编程中,如果生产者处理速度很快,而消费者处理 ...

  3. [转帖]教你如何修改运行中的docker容器的端口映射

    教你如何修改运行中的docker容器的端口映射   在docker run创建并运行容器的时候,可以通过-p指定端口映射规则.但是,我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改.当dock ...

  4. 单例模式 之 单例模式——Holder

    之前我写过 单例模式中的饿汉模式和懒汉模式 他们虽然都能实现单例模式 但是优缺点很明显 饿汉模式:不能懒加载(类加载就会被实例化),消耗很大,在并发情况下安全性很高. 懒汉模式:能实现懒加载,但是在并 ...

  5. 【一个蒟蒻的挣扎】单源最短路(Dijkstra)

    赛前没啥时间好好解释了,还有三天2019CSP,大家加油啊!!! ヾ(◍°∇°◍)ノ゙ 背掉它就好啦!!! 我觉得我这一版打得还行就放上来了 #include<cstdio> #inclu ...

  6. CSP-S 2019游记

    Day 0 下午到了广州,酒店还不错,不好的是附近没有什么吃饭的地方 zyd和ljz巨神说如果上了450就女装. 晚上看了一下写过模板,本来准备敲几个新模板的的结果被卡常,心态没了.于是又把wys的卡 ...

  7. 用Python制作动态二维码

    参考来源链接:https://mp.weixin.qq.com/s/p-ptQZD6_bjUhmU822OPww 今天在最大的同性交友社区GitHub上发现了一个比较有意思的项目,无论你是什么操作系统 ...

  8. java判断一个单向链表是否有环路

    今天刷LeetCode刷到一道这样的题,详情参见(https://leetcode-cn.com/problems/linked-list-cycle/) ADT: class ListNode { ...

  9. 在springboot中集成mybatis开发

    在springboot中利用mybatis框架进行开发需要集成mybatis才能进行开发,那么如何在springboot中集成mybatis呢?按照以下几个步骤就可以实现springboot集成myb ...

  10. ES中的查询操作

    1.前缀查询 先输入数据: PUT /my_index/address/ { "postcode": "W1 3DG" } PUT /my_index/addr ...