BZOJ1879 Bill的挑战

mac2022-06-30  143

目录

BZOJ1879 Bill的挑战题解code

BZOJ1879 Bill的挑战

题目传送门

题解

一看题目以为是道字符串题目,后来发现是个比较简单的状压\(Dp\),我们用\(g[i][j]\)数组表示匹配字符串中能否填字符\(j\)。然后记\(f[i][j]\)表示到第\(i\)位,匹配状态为\(j\)的时候方案数为多少就行了。转移还是比较简单的,最后统计状态中匹配个数恰好为\(k\)个的方案之和就行了。

code

#include <bits/stdc++.h> using namespace std; typedef long long ll; bool Finish_read; template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;} template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x+'0');} template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');} template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);} /*================Header Template==============*/ #define PAUSE printf("Press Enter key to continue..."); fgetc(stdin); const int Md=1e6+3; int f[100][100005],g[100][100]; int T,n,k; char s[100][100]; /*==================Define Area================*/ int main() { read(T); while(T--) { read(n);read(k); for(int i=1;i<=n;i++) { scanf("%s",s[i]); } memset(f,0,sizeof f); memset(g,0,sizeof g); int len=strlen(s[1]); for(int i=1;i<=len;i++) { for(char c='a';c<='z';c++) { for(int j=1;j<=n;j++) { if(s[j][i-1]=='?'||s[j][i-1]==c) g[i][c-'a']|=(1<<(j-1)); } } } f[0][(1<<n)-1]=1; for(int i=1;i<=len;i++) { for(int j=0;j<(1<<n);j++) { if(f[i-1][j]) { for(int k=0;k<26;k++) { f[i][g[i][k]&j]+=f[i-1][j]; f[i][g[i][k]&j]%=Md; } } } } int ans=0; for(int i=0;i<(1<<n);i++) { int c=0; for(int j=0;j<n;j++) { if((1<<j)&i) c++; } if(c==k) ans+=f[len][i],ans%=Md; } printf("%d\n",ans); } }

转载于:https://www.cnblogs.com/Apocrypha/p/9440917.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)