hdu5745(dp+bitset)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5745
C++ bitset的用法:https://www.cnblogs.com/magisk/p/8809922.html
题目:
题意:给两个字符串 a 和 b ,b可以进行变换,规则是可以任意交换相邻两个字符的位置,但是不可以有交叉。求a中每一个位置能不能匹配b或b变换得到的子串。
思路:dp,dp[i]表示匹配模式串前i+1个的状况,其中dp[i][0],dp[i][1],dp[i][2]分别表示和前一个交换,不交换,和后一个交换的情况,采用bitset优化。
代码:
#include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> #include<bitset> using namespace std; bitset<100005>dp[2][3],w[26]; char s[100005]; char t[5005]; int main() { int tt; int n,m; scanf("%d",&tt); while(tt--) { scanf("%d%d",&n,&m); scanf("%s%s",s,t); for(int i=0;i<26;i++)w[i].reset();//由bitset知,reset函数不带参数时将bitset的每一位置为0 for(int i=0;i<2;i++) for(int j=0;j<3;j++) dp[i][j].reset(); for(int i=0;i<n;i++) { w[s[i]-'a'][i]=1; } dp[0][1]=w[t[0]-'a']; if(m>1)dp[0][2]=w[t[1]-'a']; int now = 0; for(int i=1;i<m;i++) { now^=1; dp[now][0]=(dp[now^1][2]<<1)&w[t[i-1]-'a']; dp[now][1]=((dp[now^1][1]|dp[now^1][0])<<1)&w[t[i]-'a']; if(i<m-1) { dp[now][2]=((dp[now^1][1]|dp[now^1][0])<<1)&w[t[i+1]-'a']; } } for(int i=0;i<n;i++) { if(dp[now][0][i+m-1]||dp[now][1][i+m-1])printf("1"); else printf("0"); } puts(""); } }