正题
题目大意
对于mmm个字符串,一些地方是???表示可以填任意字符。
每一个目标串要满足至少kkk个串。
求方案总数。
解题思路
首先暴力搜索一些串选择或不选择,然后容斥。
选择之后我们可以得出一个串KKK我们称之为最终串,这时我们可以统计满足这个最终串的字符串个数。
然后我们考虑容斥,定义sumksum_ksumk表示选择kkk个串的时候的方案总数之和。
那么答案就是∑i=kmsumi∗Cmi−k∗((i−k)%2?−1:1)\sum_{i=k}^msum_i*C_m^{i-k}*((i-k)\%2\ ?\ -1:1)i=k∑msumi∗Cmi−k∗((i−k)%2 ? −1:1)
首先那个1,−11,-11,−1是容斥,然后考虑组合数的原理。
例子:{a??}{?a?}{??a}(k=2)\{a??\}\{?a?\}\{??a\}(k=2){a??}{?a?}{??a}(k=2)
这时我们发现三个串都选择时的aaaaaaaaa被多选择了3次,而这3次就是在mmm个字串中选择222个字串时方案数。
codecodecode
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int L=55,XJQ=1000003;
int m,K,l,ans,C[L];
char k[L],y[20][L];
void dfs(int dep,int c)
{if(dep>m){if(c<K) return;int w=1;for(int i=1;i<=l;i++)if(k[i]=='?') w=w*26%XJQ;ans=(ans+w*C[c-K]*(((c-K)&1)?-1:1)+XJQ)%XJQ;return;}char b[L];bool flag=1;for(int i=1;i<=l;i++){if(k[i]!='?'&&y[dep][i]!='?'&&k[i]!=y[dep][i])flag=0;b[i]=k[i];k[i]=(y[dep][i]=='?'?k[i]:y[dep][i]);}if(flag) dfs(dep+1,c+1);for(int i=1;i<=l;i++)k[i]=b[i];dfs(dep+1,c);
}
int main()
{scanf("%d%d",&m,&K);C[0]=1;for(int i=1;i<=m-K;i++)C[i]=C[i-1]*(K+i)/i%XJQ;for(int i=1;i<=m;i++)scanf("%s",y[i]+1);l=strlen(y[1]+1);for(int i=1;i<=l;i++)k[i]='?';dfs(1,0);printf("%d",ans);
}