bzoj 1879: [Sdoi2009]Bill的挑战【状压dp】
2018-09-26 16:23
225 查看
石乐志写容斥……其实状压dp就行
设f[i][s]表示前i个字母,匹配状态为s,预处理g[i][j]为第i个字母是j的1~n的集合,转移的时候枚举26个字母转移,最后答案加上正好有k个的方案即可
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int mod=1000003; int T,n,m,len,t,f[55][50005],g[55][27],ans; char c[20][55]; void jia(int &x,int y) { x+=y; if(x>mod) x-=mod; } int main() { scanf("%d",&T); while(T--) { memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%s",c[i]+1); len=strlen(c[1]+1); f[0][(1<<n)-1]=1; for(int i=1;i<=len;i++) for(int j=0;j<26;j++) for(int k=1;k<=n;k++) if(c[k][i]=='a'+j||c[k][i]=='?') g[i][j]|=1<<(k-1); for(int i=1;i<=len;i++) for(int j=0,l=(1<<n);j<l;j++) if(f[i-1][j]) for(int k=0;k<26;k++) jia(f[i][g[i][k]&j],f[i-1][j]); for(int i=0;i<(1<<n);i++) { int sm=0; for(int j=0;j<n;j++) if(i&(1<<j)) sm++; if(sm==m) jia(ans,f[len][i]); } printf("%d\n",ans); } return 0; }
相关文章推荐
- BZOJ 1879 [Sdoi2009]Bill的挑战 ——状压DP
- 【bzoj1879】【SDOI2009】【bill的挑战】【状压dp】
- BZOJ1879 [Sdoi2009]Bill的挑战 【状压dp】
- [bzoj1879][Sdoi2009]Bill的挑战_动态规划_状压dp
- 【BZOJ1879】【SDOI2009】Bill的挑战 [状压DP]
- 【BZOJ1879】[Sdoi2009]Bill的挑战 状压DP
- [bzoj 1879] [Sdoi2009]Bill的挑战:状压DP,自创数学公式(?)
- BZOJ 1879 [Sdoi2009] Bill的挑战
- [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)
- 【50.54%】【BZOJ 1879】[Sdoi2009]Bill的挑战
- bzoj 1879: [Sdoi2009]Bill的挑战
- BZOJ1879: [Sdoi2009]Bill的挑战
- bzoj千题计划207:bzoj1879: [Sdoi2009]Bill的挑战
- Bzoj1879 [Sdoi2009]Bill的挑战
- [BZOJ1879][Sdoi2009]Bill的挑战(状压DP)
- BZOJ.1879.[SDOI2009]Bill的挑战(状压DP)
- BZOJ 1879: [Sdoi2009]Bill的挑战|状压DP
- bzoj 1879 [Sdoi2009]Bill的挑战
- bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)
- bzoj 1879 [Sdoi2009]Bill的挑战