hdu5745--La Vie en rose (DP+bitset)
好题,学到新姿势!
题意:给两个字符串 a 和 b ,b可以进行变换,规则是可以任意交换相邻两个字符的位置,但是不可以有交叉(例如3和4交换,5和6交换 互不影响,但是2和3,3和4就不可以)。求a中每一个位置能不能匹配b或b变换得到的子串。
题解:考虑dp。dp[i][j][k]表示a[i]和b[j]匹配,k为1表示j未做交换,k=0表示j和j-1进行交换,k=2表示j和j+1进行交换。
直接DP会爆内存。可以想到使用滚动数组,因为递推时只与前一个状态有关。
但是加了滚动数组还是会T。
其实O(N*M)的复杂度,T了倒也很正常,但是据说各种姿势的暴力都能过,为什么这就过不去>_<
bitset优化dp
---
学习一下bitset。
可以当作一个bool型数组考虑,bitset<N> bs; 可以考虑成一个数组bool bs[N]。
相关操作:
bs.set(); 全部置1,bs.reset()全部置0;
bs.set(pos);等价于bs[pos]=1,bs.reset(pos)等价于bs[pos]=0;
最重点的来了,bitset<N> a, b;
a和b可以直接进行操作,
!a //按位取反
a^b //按位异或
a|b //按位或
a&b //按位与
a=b<<3 //整体移位
a.count(); //a中1的个数
bitset有什么用呢(也许还有其他的用处,这里讲的是本题用到的)
如果有一个bool数组 a[N] 和b[N] 把每一个位异或的话,一定是
for (int i = 0; i < N; ++i) c[i] = a[i] ^ b[i];
但是如果用bitset直接a^b的话,只需要O(N/机器字节数)
这样可以实现常数优化。
---
这和这道题有什么关系呢?
观察dp方程,
dp[i][j][] = ((dp[i-][j-][] || dp[i-][j-][]) && a[i] == b[j]);
先考虑一个,其余两个同理。
可以发现dp[i]只与dp[i-1]有关。
代码大概是这个样子的
for (int j = ; j < lb; ++j) {
for (int i = ; i < la; ++i) {
dp[i][j][] = ((dp[i-][j-][] || dp[i-][j-][]);
}
}
那么把第一位压缩,dp数组定义为bitset<N> dp[M][3] ,就可以把dp方程写成dp[j][1] = ((dp[j-1][1] | dp[j-1][0]) << 1);
这里左移是因为这里i-1求出的是i。
但是a[i]==b[j]要怎么处理呢?
因为前面是用一个bitset处理的,我们希望把a[i]==b[j]也化成一个bitset的形式,也就是对于每一个j,有一个bitset<N> bs,bs[i]其中来表示a[i]==b[j]的值,但是这样又是N*M,明显不可能的,其实不需要对于每一个j都有一个bitset,因为一共有26个字母,于是只需对每一个字母求出,即bitset<N>26,然后使用b[j]那个的字母bitset就可以了。
至于滚动数组就很好实现了,
这题正解反而卡常数卡的厉害,姿势不对很容易超时,没人性!! T^T
AC代码(3166MS)
#include <cstdio>
#include <bitset>
#include <iostream>
#include <cstring>
using namespace std;
const int N = ;
const int M = ;
char a[N];
char b[M];
//bool dp[N][M][3]; 0和前面的交换 1不交换 2和后面的交换
bitset<N> dp[][];
bitset<N> w[]; // 记录对于每个字母 p[i]是否为这个字母
int main()
{
//freopen("in", "r", stdin);
int T;
int la, lb;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &la, &lb);
scanf("%s%s", a, b); for (int i = ; i < ; ++i) w[i].reset();
for (int i = ; i < la; ++i) w[a[i]-'a'][i] = ;
for (int i = ; i < ; ++i) for (int j = ; j < ; ++j) dp[i][j].reset();
dp[][] = w[b[]-'a'];
if (lb > ) dp[][] = w[b[]-'a']; int now = ;
for (int j = ; j < lb; ++j) {
now ^= ;
dp[now][] = ((dp[now^][]) << ) & w[b[j-]-'a'];
dp[now][] = ((dp[now^][] | dp[now^][]) << ) & w[b[j]-'a'];
if (j < lb - ) dp[now][] = ((dp[now^][] | dp[now^][]) << ) & w[b[j+]-'a'];
} for (int i = ; i < la; ++i) {
if (dp[now][][i+lb-] || dp[now][][i+lb-]) printf("");
else printf("");
}
puts(""); }
return ;
}
hdu5745--La Vie en rose (DP+bitset)的更多相关文章
- hdu 5745 La Vie en rose DP + bitset优化
http://acm.hdu.edu.cn/showproblem.php?pid=5745 这题好劲爆啊.dp容易想,但是要bitset优化,就想不到了. 先放一个tle的dp.复杂度O(n * m ...
- hdu5745 La Vie en rose 巧妙地dp+bitset优化+滚动数组减少内存
/** 题目:hdu5745 La Vie en rose 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5745 题意:题目给出的变换规则其实就是交换相邻 ...
- HDU 5745 La Vie en rose (DP||模拟) 2016杭电多校联合第二场
题目:传送门. 这是一道阅读理解题,正解是DP,实际上模拟就能做.pij+1 指的是 (pij)+1不是 pi(j+1),判断能否交换输出即可. #include <iostream> # ...
- HDU 5745 La Vie en rose 暴力
La Vie en rose 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5745 Description Professor Zhang woul ...
- HDU 5745 La Vie en rose
La Vie en rose Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- hdu 5745 La Vie en rose(2016多校第二场)
La Vie en rose Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- La Vie en rose (模拟)
#include<bits/stdc++.h> using namespace std; ; ; int T, n, m; char str1[maxm], str2[maxn]; int ...
- HDU5716, HDU5745【dp+bitset】
DP+bitset HDU5716 dp[i][j] = dp[i-1][j-1] && (s[i] in set[j]); 第二维压bitset #include <bits ...
- 字符串匹配dp+bitset,滚动数组优化——hdu5745(经典)
bitset的经典优化,即把可行性01数组的转移代价降低 bitset的适用情况,当内层状态只和外层状态的上一个状态相关,并且内层状态的相关距离是一个固定的数,可用bitset,换言之,能用滚动数组是 ...
随机推荐
- 1.The Necessity of a Broad Education 全面教育的必要性
1.The Necessity of a Broad Education 全面教育的必要性 (1) According to a survey,which was based on the respo ...
- 使用spring boot +WebSocket实现(后台主动)消息推送
言:使用此webscoket务必确保生产环境能兼容/支持!使用此webscoket务必确保生产环境能兼容/支持!使用此webscoket务必确保生产环境能兼容/支持!主要是tomcat的兼容与支持. ...
- Oracle 除数为0的处理(decode)
select (a/b*100)per from aa; 当b为0时,提示除数为0, 本人想当除数为0时,不让系统提示出错,结果显示0即可? 解决:select d ...
- error C4430: error 2141
c:\evan\workspace\1\1\netwowkippack.h(50) : error C2146: 语法错误 : 缺少“;”(在标识符“nSourPort”的前面) c:\evan\wo ...
- 学习fortran77基础语法
Program ParamaterDefine Implicit None C FORTRAN变量名和关键字不区分大小写.但调用外部函数的话,需要在编译选项里指定 c 大小写等选项 因为链接器是区分大 ...
- IntelliJ IDEA 2017版 Spring5最基本的bean例子创建
一.简述 SpringBoot是基于spring框架之上的快速开发的框架.Spring4核心就是容器,容器提供了对bean的装配和管理. spring依赖加载: ...
- 学以致用十二-----YouCompeteMe巨坑
接上一篇,通过这几天的不断尝试,发现一个无法解决的问题.至于我安装成功的那台,我至今不知道是安装了哪一步导致成功的. 首先,我在.vimrc里加上了 Plugin 'Valloric/YouComp ...
- 学以致用一 安装centos7.2虚拟机
5说来惭愧,也是很久没来博客园了.距离上次写的已经快一年,只能说时间过的真的很快. 而如果这一年一直在坚持认真学习的话,收获肯定很多.然而我确又浪费了很多光阴,不得不恨这人生苦短. 在这一年里,小孩还 ...
- [待完善]mycat分布式架构部署
mycat介绍:http://mycat.org.cn/ mycat分布式架构部署
- UNIX之父肯和丹尼斯(连载二)
从那一场“黑客招聘会”说起 2012年7月末在拉斯维加斯召开的全球黑客大会,已经是这系列会议的第二十一次.除了惯常的Bug发表.技术展示之外,最近几年的黑客大会也开始变得越来越像招聘会.IT业 ...