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. /*-- ...
随机推荐
- java.lang.ClassNotFoundException: org.hibernate.annotations.common.reflection.MetadataProvider
Caused by: java.lang.NoClassDefFoundError: org/hibernate/annotations/common/reflection/MetadataProvi ...
- 函数 xdes_get_descriptor_with_space_hdr
获得区描述符 xdes entry 的offset /********************************************************************//** ...
- NoSQL开篇——为什么要使用NoSQL
NoSQL在2010年风生水起,大大小小的Web站点在追求高性能高可靠性方面,不由自主都选择了NoSQL技术作为优先考虑的方面.今年伊始,InfoQ中文站有幸邀请到凤凰网的孙立先生,为大家分享他之于N ...
- 解决魅族USB调试无法被电脑识别的问题(含Mac OS X、Win7)
每次打开豌豆荚或者360手机助手之类手机助手后Eclipse才会检测到mx4(实际上是豌豆荚关闭eclipse的adb使用自己的驱动连接的).解决方法就是在"adb_usb.ini&qu ...
- 【C#学习笔记】类构造函数使用
using System; namespace ConsoleApplication { class stu { private string name; private int age; publi ...
- 【web】web欢迎页面执行servlet
<!-- servlet名 --> <welcome-file-list> <welcome-file>Begin_page</welcome-file> ...
- Java应用调优指南之-工具篇
1. 土法调优两大件 先忆苦思甜,一般人在没有Profile工具的时候,调优的两大件,无非Heap Dump 与 Thread Dump. 1.1 Heap Dump jmap -dump:live, ...
- system函数的总结
最近在看APUE第10章中关于system函数的POSIX.1的实现.关于POSIX.1要求system函数忽略SIGINT和SIGQUIT,并且阻塞信号SIGCHLD的论述,理解得不是很透彻,本文就 ...
- Iwpriv工作流程及常用命令使用
iwpriv工具通过ioctl动态获取相应无线网卡驱动的private_args所有扩展参数 iwpriv是处理下面的wlan_private_args的所有扩展命令,iwpriv的实现上,是这样的, ...
- bzoj 2229 [Zjoi2011]最小割(分治+最小割)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2229 [题意] 回答若干个关于割不超过x的点对数目的询问. [思路] [最小割最多有n ...