/**
题目:hdu5745 La Vie en rose
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5745
题意:题目给出的变换规则其实就是交换相邻元素, 并且每个元素最多交换一次.
思路:
那么一个O(nm)的dp其实十分显然, dp_{i,j,k}
​​ 表示匹配到s的第i个字符, p的第j个字符, j这一位的当前状态是k (0表示和前面交换, 1表示没有交换, 2表示和后面交换). 转移方程如下:
dp[i][j][0] = dp[i-1][j-1][2]&&(s[i]==p[j-1]);
dp[i][j][1] = (dp[i-1][j-1][0]||dp[i-1][j-1][1])&&(s[i]==p[j]);
dp[i][j][2] = (dp[i-1][j-1][0]||dp[i-1][j-1][1])&&(s[i]==p[j+1]);
这个dp数组里面存的都是bool值, 可以考虑用bitset压缩这个dp数组中的第一维i, 然后滚动下第二维j, 就得到了O(N*M/W)的做法, 其中w是机器的字节长. */ /*
未用bitset优化前。
用一个滚动数组减少内存。
直接把枚举p串的那层循环放到第一层,然后滚动。 #include<iostream>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm>
#include<queue>
using namespace std;
typedef unsigned int ut;
typedef long long LL;
const int N = 1e5+1;
const int M = 5e3+1;
int dp[N][2][3];
char s[N], p[M];
int main()
{
int T;
int n, m;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
scanf("%s",s+1);
int ls = strlen(s+1);
scanf("%s",p+1);
int lp = strlen(p+1);
int d = 0;
for(int j = 1; j <= lp; j++){
for(int i = 1; i <= ls; i++){
if(j==1){
dp[i][d][0] = 0;
dp[i][d][1] = s[i]==p[j];
dp[i][d][2] = s[i]==p[j+1];
}else{
dp[i][d][0] = dp[i-1][d^1][2]&&(s[i]==p[j-1]);
dp[i][d][1] = (dp[i-1][d^1][0]||dp[i-1][d^1][1])&&(s[i]==p[j]);
dp[i][d][2] = (dp[i-1][d^1][0]||dp[i-1][d^1][1])&&(s[i]==p[j+1]);
}
}
d^=1;
}
for(int i = m; i <= ls; i++){
printf("%d",dp[i][d^1][0]||dp[i][d^1][1]);
}
for(int i = 1; i < m; i++){
printf("0");
}
printf("\n");
}
return 0;
} */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm>
#include<queue>
using namespace std;
typedef unsigned int ut;
typedef long long LL;
const int N = 1e5+;
const int M = 5e3+;
bitset<N> dp[][];
bitset<N> alp[];
char s[N], p[M];
int main()
{
int T;
int n, m;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
scanf("%s",s+);
int ls = strlen(s+);
scanf("%s",p+);
int lp = strlen(p+);
for(int i = ; i < ; i++) alp[i].reset();
for(int i = ; i < ; i++){
for(int j = ; j < ; j++){
dp[i][j].reset();
}
}
for(int i = ; i <= ls; i++){
alp[s[i]-'a'][i] = ;///alp[i][j]表示i+'a'这个字符在s字符串的j位置出现过。
}
dp[][] = alp[p[]-'a'];///dp[i][j][k]表示p字符串的位置i与s字符串的位置k,j=0表示i-1位置,j=1表示i位置,j=2表示i+1位置。
///所以dp[0][1]=alp[p[1]-'a'];和p字符串i位置相同的s字符串的k位置集合。
if(lp>=)
dp[][] = alp[p[]-'a'];
int d = ;
for(int j = ; j <= lp; j++){
dp[d][] = (dp[d^][]<<)&alp[p[j-]-'a'];
dp[d][] = ((dp[d^][]|dp[d^][])<<)&alp[p[j]-'a'];
if(j+<=lp)
dp[d][] = ((dp[d^][]|dp[d^][])<<)&alp[p[j+]-'a'];
d^=;
}
for(int i = m; i <= ls; i++){
printf("%d",dp[d^][][i]||dp[d^][][i]);
}
for(int i = ; i < m; i++){
printf("");
}
printf("\n");
}
return ;
}

hdu5745 La Vie en rose 巧妙地dp+bitset优化+滚动数组减少内存的更多相关文章

  1. HDU5745-La Vie en rose-字符串dp+bitset优化

    这题现场的数据出水了,暴力就能搞过. 标解是拿bitset做,转移的时候用bitset优化过的操作(与或非移位)来搞,复杂度O(N*M/w) w是字长 第一份标程的思路很清晰,然而后来会T. /*-- ...

  2. HDU 5745 La Vie en rose 暴力

    La Vie en rose 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5745 Description Professor Zhang woul ...

  3. 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 ...

  4. 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 ...

  5. hdu 5745 La Vie en rose DP + bitset优化

    http://acm.hdu.edu.cn/showproblem.php?pid=5745 这题好劲爆啊.dp容易想,但是要bitset优化,就想不到了. 先放一个tle的dp.复杂度O(n * m ...

  6. 字符串匹配dp+bitset,滚动数组优化——hdu5745(经典)

    bitset的经典优化,即把可行性01数组的转移代价降低 bitset的适用情况,当内层状态只和外层状态的上一个状态相关,并且内层状态的相关距离是一个固定的数,可用bitset,换言之,能用滚动数组是 ...

  7. HDU 5745 La Vie en rose (DP||模拟) 2016杭电多校联合第二场

    题目:传送门. 这是一道阅读理解题,正解是DP,实际上模拟就能做.pij+1 指的是 (pij)+1不是 pi(j+1),判断能否交换输出即可. #include <iostream> # ...

  8. La Vie en rose (模拟)

    #include<bits/stdc++.h> using namespace std; ; ; int T, n, m; char str1[maxm], str2[maxn]; int ...

  9. hdu5745--La Vie en rose (DP+bitset)

    好题,学到新姿势! 题意:给两个字符串 a 和 b ,b可以进行变换,规则是可以任意交换相邻两个字符的位置,但是不可以有交叉(例如3和4交换,5和6交换 互不影响,但是2和3,3和4就不可以).求a中 ...

随机推荐

  1. SqlBulkCopy-从 bcp 客户端收到一个对 colid 1 无效的列长度

    经过研究,问题是因为tatatable中的colid列1的数据字段长度超过了数据表中定义的字段长度. 解决方法就是将数据库该字段的长度增大问题就解决了.

  2. Short与Integer互转

    int 是4字节, short 是2字节的, 如果将int(Integer)转成short(Short), 那么必须强制转换,否则会报编译异常. 但是, 当int(Integer)是一个final时, ...

  3. IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

    本文引用了简书作者“骑小猪看流星”技术文章“Cookie.Session.Token那点事儿”的部分内容,感谢原作者. 1.前言 众所周之,IM是个典型的快速数据流交换系统,当今主流IM系统(尤其移动 ...

  4. js实现选择及复制粘贴

    最近项目有个点击复制到粘贴板的需求,在这里做一个简单的例子分享给大家,没考虑兼容性,需要兼容的大家去查找下文档 //html<p id="element">测试测试&l ...

  5. vue - config(index.js)

    描述:我想,这是调用最多的一个文件了吧(无论是dev,还是prod) 'use strict' // Template version: 1.3.1 // see http://vuejs-templ ...

  6. 算法笔记_102:蓝桥杯练习 算法提高 快乐司机(Java)

    目录 1问题描述 2 解决方案   1 问题描述 问题描述 "嘟嘟嘟嘟嘟嘟 喇叭响 我是汽车小司机 我是小司机 我为祖国运输忙 运输忙" 这是儿歌“快乐的小司机”.话说现在当司机光 ...

  7. Java学习笔记1、常用dos命令

    cd 改变当前目录 sys      制作DOS系统盘 copy 拷贝文件 del 删除文件 deltree 删除目录树 dir 列文件名 diskcopy 制磁盘 edit 文本编辑 format ...

  8. 创建win32窗口

    #include <windows.h> LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HIN ...

  9. RSA/DSA 密钥的工作原理

    下面从整体上粗略的介绍了 RSA/DSA 密钥的工作原理.让我们从一种假想的情形开始,假定我们想用 RSA 认证允许一台本地的 Linux 工作站(称作 localbox)打开 remotebox 上 ...

  10. Android源代码装饰模式---ContextWrapper

    假设说Android源代码中哪个地方装饰模式应用的最明显的话,那肯定是非ContextWrapper莫属了,ContextWrapper是一个透明的经典的装饰模式.本文将通过装饰器模式分析Contex ...