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 A and B is 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 either A or B. 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:

  • ABAAABA
  • ABAABBA
  • ABBAABA
  • ABBABBA

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;
}
posted @ 2025-04-16 20:39  usedchang  阅读(30)  评论(0)    收藏  举报