P2167 [SDOI2009] Bill的挑战题解

P2167 [SDOI2009] Bill的挑战

题目描述

Sheng_bill 不仅有惊人的心算能力,还可以轻松地完成各种统计。在昨天的比赛中,你凭借优秀的程序与他打成了平局,这导致 Sheng_bill 极度的不满。于是他再次挑战你。这次你可不能输。

这次,比赛规则是这样的:

给出 NNN 个长度相同的字符串(由小写英文字母和 ? 组成),S1,S2,…,SNS_1,S_2,\dots,S_NS1,S2,,SN,求与这 NNN 个串中的刚好 KKK 个串匹配的字符串 TTT 的个数,答案对 100000310000031000003 取模。

若字符串 Sx(1≤x≤N)S_x(1\le x\le N)Sx(1xN)TTT 匹配,满足以下条件:

  1. ∣Sx∣=∣T∣|S_x|=|T|Sx=T
  2. 对于任意的 1≤i≤∣Sx∣1\le i\le|S_x|1iSx,满足 Sx[i]=?S_x[i]= \texttt{?}Sx[i]=? 或者 Sx[i]=T[i]S_x[i]=T[i]Sx[i]=T[i]

其中 TTT 只包含小写英文字母。

输入格式

本题包含多组数据

第一行一个整数 TTT,表示数据组数。

对于每组数据,第一行两个整数,NNNKKK

接下来 NNN 行,每行一个字符串 SiS_iSi

输出格式

每组数据输出一行一个整数,表示答案。

输入输出样例 #1

输入 #1

5
3 3
???r???
???????
???????
3 4
???????
?????a?
???????
3 3
???????
?a??j??
????aa?
3 2
a??????
???????
???????
3 2
???????
???a???
????a??

输出 #1

914852
0
0
871234
67018

说明/提示

数据规模与约定

  • 对于 30%30\%30% 的数据,N≤5N\le5N5∣Si∣≤20|S_i|\le20Si20
  • 对于 70%70\%70% 的数据,N≤13N\le13N13∣Si∣≤30|S_i|\le30Si30
  • 对于 100%100\%100% 的数据,1≤T≤51\le T\le 51T51≤N≤151\le N \le151N151≤∣Si∣≤501\le|S_i|\le501Si50

思路

DP即可。

代码见下

#include<bits/stdc++.h>
#define mod 9999973
using namespace std;
long long n,m,f[105][105][105],op=0;
int main(){
    cin>>n>>m;
    f[0][0][0]=1;
    for(int i=0;i<=n-1;i++){
        for(int j=0;j<=m;j++){
            for(int k=0;k+j<=m;k++){
                if(j>=1){
                    f[i+1][j-1][k+1]=(f[i+1][j-1][k+1]+f[i][j][k]*j)%mod;
                }
                if(m-j-k>=1){
                    f[i+1][j+1][k]=(f[i+1][j+1][k]+f[i][j][k]*(m-j-k))%mod;
                }
                if(j>=2){
                    f[i+1][j-2][k+2]=(f[i+1][j-2][k+2]+f[i][j][k]*j*(j-1)/2)%mod;
                }
                if(m-j-k>=2){
                    f[i+1][j+2][k]=(f[i+1][j+2][k]+f[i][j][k]*(m-j-k)*(m-j-k-1)/2)%mod;
                }
                if(m-j-k>=1&&j>=1){
                    f[i+1][j][k+1]=(f[i+1][j][k+1]+f[i][j][k]*(m-j-k)*j)%mod;
                }
                f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%mod;
            }
        }
    }
    op=0;
    op=0;
    for(int i=0;i<=m;i++){
        for(int j=0;j+i<=m;j++){
            op=(op+f[n][i][j])%mod;
        }
    }
    cout<<op<<endl;
	return 0;
}
posted @ 2025-11-17 21:27  bz02_2023f2  阅读(4)  评论(0)    收藏  举报  来源