BZOJ 2121: 字符串游戏 区间DP + 思维
Description
Input
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 + 思维的更多相关文章
- BZOJ#2121. 字符串游戏 [区间dp]
// powered by c++11 // by Isaunoya #include<bits/stdc++.h> #define rep(i , x , y) for(register ...
- 【bzoj2121】字符串游戏 区间dp
题目描述 给你一个字符串L和一个字符串集合S,如果S的某个子串在S集合中,那么可以将其删去,剩余的部分拼到一起成为新的L串.问:最后剩下的串长度的最小值. 输入 输入的第一行包含一个字符串,表示L. ...
- BZOJ 1090 字符串折叠(区间DP)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1090 题意:字符串AAAAAAAAAABABABCCD的最短折叠为9(A)3(AB)CC ...
- BZOJ2121: 字符串游戏(DP)(字符串删单词,求最多可以删去多少)
2121: 字符串游戏 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 672 Solved: 376[Submit][Status][Discuss ...
- 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 ...
- 【BZOJ-1090】字符串折叠 区间DP + Hash
1090: [SCOI2003]字符串折叠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1127 Solved: 737[Submit][Stat ...
- 洛谷P4302 [SCOI2003]字符串折叠(区间dp)
题意 题目链接 Sol 裸的区间dp. 转移的时候枚举一下断点.然后判断一下区间内的字符串是否循环即可 `cpp #include<bits/stdc++.h> #define Pair ...
- BZOJ 1055 玩具取名(区间DP)
很显然的区间DP,定义dp[i][j][k], 如果dp[i][j][k]=1表示字符串[i,j]可以组成k字符. # include <cstdio> # include <cst ...
- bzoj 1068 [SCOI2007]压缩 区间dp
[SCOI2007]压缩 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 1644 Solved: 1042[Submit][Status][Discu ...
随机推荐
- 【VS开发】error C2220: 警告被视为错误 - 没有生成“object”文件
http://blog.csdn.net/cay22/article/details/5613625 这种错误的原因是:原因是该文件的代码页为英文,而我们系统中的代码页为中文. 解决方案: 1. 启动 ...
- selenium:css_selector定位详解
selenium:css_selector定位详解(css selector和xpath的比较) 来源:https://www.cnblogs.com/haifeima/p/10138154.html ...
- react 中 EventEmitter 事件总线机制
此机制可用于 react 中兄弟组件中的通信 npm install events -S 事件总线: // eventBus.js import {EventEmitter} from 'events ...
- vue --- vscode 配置 .vue文件生成结构
1.选择“文件 -> 首选项 -> 用户代码片段”,此时,会弹出一个搜索框,输入vue 选择vue后,编辑器会自动打开一个名字为vue.json的文件 2.复制以下内容到这个文件 ...
- [转帖]紫光与群联联盟,长江存储NAND+群联主控+紫光品牌SSD可期
紫光与群联联盟,长江存储NAND+群联主控+紫光品牌SSD可期 全国产的 SSD https://baijiahao.baidu.com/s?id=1620789429952097018&wf ...
- mysql整理-常用sql语句
一.常用sql show variables like 'character_set_client';#查询字符集 show databases;#列出所有的服务器上的数据库alter create ...
- 搜索专题:问题 E: 挑战ACM迷宫
这是往年校赛的一道题,最开始做这道题的时候还没有系统的学习过搜索,用了C语言学的回溯法尝试,毫无疑问的TLE: 学习了DFS之后,自己的剪枝功力不够,又是TLE,最后学了BFS之后,哇,终于做出来了, ...
- linux 配置环境变量三种方式
一:用于当前终端: export PATH=$PATH:<你的要加入的路径> 此方式仅用于当前终端,一旦该终端关闭,则配置失效 二:用于当前用户: vi ~/.bashrc 然后加入:ex ...
- 创建Django项目的过程
1.创建Django项目根目录 a.命令式创建法:Django-admin startproject 项目名称 b.pycharm创建法:如下图 2.配置setting环境 a.配置静态文件 STAT ...
- 从分析攻击方式来谈如何防御DDoS攻击
DDoS攻击的定义: DDoS攻击全称——分布式拒绝服务攻击,是网络攻击中非常常见的攻击方式.在进行攻击的时候,这种方式可以对不同地点的大量计算机进行攻击,进行攻击的时候主要是对攻击的目标发送超过其处 ...