题目:
题意:
给出一些长度相同的句子,求若按照其他句子的样式将某些句子中的 ? ? ?填充上,总共有多少种不同的意思
分析:
设
s
u
m
i
sum_i
sumi为选择
i
i
i个句子后的方案数总和
k
k
k为所有句子的最终形式
那么答案就是
∑
m
i
=
k
s
u
m
i
∗
C
m
i
−
k
∗
(
(
i
−
k
)
%
2
?
−
1
:
1
)
∑_m^{i=k}sum_i∗C_m^{i-k}∗((i−k)\%2 ? −1:1)
∑mi=ksumi∗Cmi−k∗((i−k)%2?−1:1)
后面的
−
1
、
1
-1、1
−1、1是因为我们需要考虑到容斥
代码:
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define LZX 1000003
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
using namespace std;
char s[20][55],miao[55];
int c[20],ans=0,len;
int m=read(),k=read();
void dfs(int i,int sum)
{
if(i>m)
{
if(sum<k) return;
int w=1;
for(int j=1;j<=len;j++) if(miao[j]=='?') (w*=26)%=LZX;
(ans+=w*c[sum-k]*((sum-k)&1?-1:1)+LZX)%=LZX;
return;
}
char x[55];
int tf=1;
for(int j=1;j<=len;j++)
{
if(miao[j]!='?'&&s[i][j]!='?'&&miao[j]!=s[i][j]) tf=0;
x[j]=miao[j];
miao[j]=(s[i][j]=='?'?miao[j]:s[i][j]);
}
if(tf) dfs(i+1,sum+1);
for(int j=1;j<=len;j++) miao[j]=x[j];
dfs(i+1,sum);
return;
}
int main()
{
for(int i=1;i<=m;i++) scanf("%s",s[i]+1);
len=strlen(s[1]+1);
c[0]=1;
for(int i=1;i<=m-k;i++) c[i]=c[i-1]*(k+i)/i%LZX;
for(int i=1;i<=len;i++) miao[i]='?';
dfs(1,0);
cout<<ans;
return 0;
}