At359 D - Avoid K Palindrome
D.Avoid K Palindrome
Problem Statement
You are given a string \(S\) of length \(N\) consisting of characters
A,B, and?.You are also given a positive integer \(K\). A string \(T\) consisting of
AandBis considered a good string if it satisfies the following condition:
- No contiguous substring of length \(K\) in \(T\) is a palindrome.
Let \(q\) be the number of
?characters in \(S\). There are \(2^q\) strings that can be obtained by replacing each?in \(S\) with eitherAorB. Find how many of these strings are good strings.The count can be very large, so find it modulo \(998244353\).
Constraints:
- \(2 \leq K \leq N \leq 1000\)
- \(K \leq 10\)
- \(S\) is a string consisting of
A,B, and?.- The length of \(S\) is \(N\).
- \(N\) and \(K\) are integers.
Sample Input:
7 4
AB?A?BA
Sample Output:
1
The given string has two ?s. There are four strings obtained by replacing each ? with A or B:
ABAAABAABAABBAABBAABAABBABBA
Among these, the last three contain the contiguous substring ABBA of length 4, which is a palindrome, and thus are not good strings.
Therefore, you should print 1.
解题思路:
观察发现数据范围十分小,可以通过暴力转移的代码 O(2k·n),考虑状态压缩,
1对应A,0对应B,?的时候两种状态都进行枚举
在枚举到的区间小于k的时候默认肯定不能构成长为k的回文子串,
在枚举区间等于k的时候可以通过左边界和右边界同时右移保证区间长度是k,判断每一个长为k的区间。
AC code1:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int mod=998244353;
int main(){
cin.tie(0)->ios::sync_with_stdio(false);
int n,k;cin>>n>>k;
string s;cin>>s;
vector f(n+2,vector<ll>(2050));
auto check=[&](int x)->bool{
for(int i=0;i<k;i++){
int low=(x>>i&1);
int high=(x>>(k-1-i)&1);
if(low!=high) return 1;
}
return 0;
};
if(s[0]!='B') f[0][1<<(k-2)]=1;
if(s[0]!='A') f[0][0]=1;
for(int i=1;i<n;i++){
for(int x=0;x<(1<<k-1);x++){
if(s[i]!='B'&&(i<k-1||check(x|(1<<k-1)))){
(f[i][x>>1|1<<(k-2)]+=f[i-1][x])%=mod;
}
if(s[i]!='A'&&(i<k-1||check(x))){
(f[i][x>>1]+=f[i-1][x])%=mod;
}
}
}
ll ans=0;
for(int i=0;i<(1<<k-1);i++) (ans+=f[n-1][i])%=mod;
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号