hdu 5745 La Vie en rose DP + bitset优化
http://acm.hdu.edu.cn/showproblem.php?pid=5745
这题好劲爆啊。dp容易想,但是要bitset优化,就想不到了。
先放一个tle的dp。复杂度O(n * m)的
第一个串,记作str[],第二个记作sub[]
思路就是,设dp[i][j][k]表示,匹配了sub的前i个,以str的第j个结尾,然后sub[i]有三种状态,0表示不变化,1表示和前一个,2表示和后一个。
那么以求dp[i][j][0]为列
因为需要的是判断str的第j个结尾是否和sub的前i个完全匹配。
那么,要使得dp[i][j][0]为true,必然需要前i - 1个和j - 1个匹配成功。就是要递推过来。
那么dp[i][j][0] = (dp[i - 1][j - 1][0] || dp[i - 1][j - 1][1]) && (str[j] == sub[i])
其他的类似啦。
可以滚动下数组。
不清0的话,直接用DFN代替即可。这样的复杂度就是O(n * m),没有常数。但是还是TLE.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + ;
char str[maxn], sub[maxn];
int dp[][maxn][];
int DFN;
char ans[maxn];
void work() {
DFN++;
int lenstr, lensub;
scanf("%d%d", &lenstr, &lensub);
scanf("%s", str + );
scanf("%s", sub + );
// dp[0][0][0] = DFN;
for (int i = ; i <= lenstr; ++i) dp[][i][] = DFN;
int now = ;
for (int i = ; i <= lensub; ++i) {
now = !now;
for (int j = ; j <= lenstr; ++j) {
// if ((dp[i - 1][j - 1][0] || dp[i - 1][j - 1][1]) && str[j] == sub[i]) {
// dp[i][j][0] = true;
// }
// if (dp[i - 1][j - 1][2] && str[j] == sub[i - 1]) {
// dp[i][j][1] = true;
// }
// if ((dp[i - 1][j - 1][0] || dp[i - 1][j - 1][1]) && sub[i + 1] == str[j]) {
// dp[i][j][2] = true;
// }
if ((dp[!now][j - ][] == DFN || dp[!now][j - ][] == DFN) && str[j] == sub[i]) {
dp[now][j][] = DFN + ;
}
if (dp[!now][j - ][] == DFN && str[j] == sub[i - ]) {
dp[now][j][] = DFN + ;
}
if ((dp[!now][j - ][] == DFN || dp[!now][j - ][] == DFN) && str[j] == sub[i + ]) {
dp[now][j][] = DFN + ;
}
}
DFN++;
}
for (int i = ; i <= lenstr; ++i) {
ans[i] = '';
if (dp[now][i][] == DFN || dp[now][i][] == DFN || dp[now][i][] == DFN) {
// printf("1");
ans[i - lensub + ] = '';
}
}
ans[lenstr + ] = '\0';
printf("%s\n", ans + );
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
然后百度了一个bitset的优化。
考虑用bitset<1e5> dp[5000][k]
dp[i][k]
表示,处理了sub的前i个,当前sub的状态是k,然后匹配整个str串的结果就是dp[i][k],因为dp[i][k]是一个长度为1e5的01串嘛。也就是dp[i][k]就是匹配好的结果了。
那么,要快速计算dp[i][0],只需要(dp[i - 1][0] | dp[i - 1][1]) << 1
比如前2个匹配好的结果是"10"和"11"然后匹配成的第三位,就是"011",关键看看第三位,是1,也就是上面的dp[i - 1][j - 1][k] = true的意思。就是前面的匹配好了,但是还要看看str[j]和sub[i]的相等情况。
要想这一位是true,必然要这一位和sub对应相等。但是我们一次要算出整一个结果,而不是一个一个地算,那么,预处理个pos[26]的bitset就可以,&一下,就是要对应位置是1的,才是true。
3478ms,我是卡过去的

后来一直TLE
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset> const int maxn = 1e5 + ;
bitset<maxn> dp[][];
char str[maxn], sub[maxn];
bitset<maxn>pos[]; void init() {
for (int i = ; i <= ; ++i) {
for (int j = ; j <= ; ++j) {
dp[i][j].reset();
}
}
for (int i = ; i < ; ++i) pos[i].reset();
}
char ans[maxn];
void work() {
init();
int lenstr, lensub;
scanf("%d%d", &lenstr, &lensub);
scanf("%s%s", str + , sub + );
for (int i = ; i <= lenstr; ++i) {
pos[str[i] - 'a'][i] = ;
}
dp[][] = pos[sub[] - 'a'];
if (lensub >= ) dp[][] = pos[sub[] - 'a'];
int now = ;
for (int i = ; i <= lensub; ++i) {
now = !now;
dp[now][] = ((dp[!now][] | dp[!now][]) << ) & pos[sub[i] - 'a'];
dp[now][] = (dp[!now][] << ) & pos[sub[i - ] - 'a'];
if (i < lensub) {
dp[now][] = ((dp[!now][] | dp[!now][]) << ) & pos[sub[i + ] - 'a'];
}
}
for (int i = ; i <= lenstr; ++i) {
if (i + lensub - > lenstr) {
ans[i] = '';
} else {
if (dp[now][][i + lensub - ] || dp[now][][i + lensub - ]) {
ans[i] = '';
} else ans[i] = '';
}
}
ans[lenstr + ] = '\0';
printf("%s\n", ans + );
// printf("\n");
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
hdu 5745 La Vie en rose DP + bitset优化的更多相关文章
- 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 ...
- hdu5745--La Vie en rose (DP+bitset)
好题,学到新姿势! 题意:给两个字符串 a 和 b ,b可以进行变换,规则是可以任意交换相邻两个字符的位置,但是不可以有交叉(例如3和4交换,5和6交换 互不影响,但是2和3,3和4就不可以).求a中 ...
- hdu5745 La Vie en rose 巧妙地dp+bitset优化+滚动数组减少内存
/** 题目:hdu5745 La Vie en rose 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5745 题意:题目给出的变换规则其实就是交换相邻 ...
- La Vie en rose (模拟)
#include<bits/stdc++.h> using namespace std; ; ; int T, n, m; char str1[maxm], str2[maxn]; int ...
- HDU 5313——Bipartite Graph——————【二分图+dp+bitset优化】
Bipartite Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- HDU5745-La Vie en rose-字符串dp+bitset优化
这题现场的数据出水了,暴力就能搞过. 标解是拿bitset做,转移的时候用bitset优化过的操作(与或非移位)来搞,复杂度O(N*M/w) w是字长 第一份标程的思路很清晰,然而后来会T. /*-- ...
随机推荐
- ASP.NET MVC 学习2、从Controller传递数据到View
参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-view 一,Control ...
- (任寒韬)WebApp群主 - MobileTech 资料
web app : http://www.lightapp.cn/brand/index/4101 https://github.com/jtyjty99999/mobileTech/blob/mas ...
- Android Dialog使用举例
在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,在我们使用Android的过程中,我归纳了一 ...
- Web API入门指南(安全)转
安全检测的工具站点:https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools Web API入门指南有些朋友回复问了些 ...
- 【大数取模】HDOJ-1134、CODEUP-1086
1086: 大数取模 题目描述 现给你两个正整数A和B,请你计算A mod B.为了使问题简单,保证B小于100000. 输入 输入包含多组测试数据.每行输入包含两个正整数A和B.A的长度不超过1 ...
- 零基础编程指南(By Turtle)
[零.基础] 1.看文章:<程序猿搜索的技巧>(未完成) [一.入门] 学习语言:VB 安装:下载VB6即可 教程:<李天生vb从入门到精通>http://www.xin372 ...
- [shell]通过ping检测整个网段IP的网络状态脚本
要实现Ping一个网段的所有IP,并检测网络连接状态是否正常,很多方法都可以实现,下面简单介绍两种,如下:脚本1#!/bin/sh# Ping网段所有IP# 2012/02/05ip=1 #通过修改初 ...
- 值班问题:insert语句插入了两条数据?
上周值班,碰到这样的一个客户问题,表结构简化如下: CREATE TABLE `aa` (`c1` int(10) unsigned NOT NULL AUTO_INCREMENT,`c2` int( ...
- [Papers]MHD, $\pi$, Lorentz space [Suzuki, DCDSA, 2011]
$$\bex \sen{\pi}_{L^{s,\infty}(0,T;L^{q,\infty}(\bbR^3))} +\sen{{\bf b}}_{L^{\gamma,\infty}(0,T;L^{\ ...
- MyBatis 物理分页
MyBatis使用RowBounds实现的分页是逻辑分页,也就是先把数据记录全部查询出来,然在再根据offset和limit截断记录返回 为了在数据库层面上实现物理分页,又不改变原来MyBatis的函 ...