bzoj1072: [SCOI2007]排列perm
状压dp。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 12; int f[1<<maxn][1010],cnt[maxn],fac[maxn]; char s[maxn]; int T,d,N,n; int main() { fac[0]=1; for(int i=1;i<=10;i++) fac[i]=fac[i-1]*i; scanf("%d",&T); while(T--) { memset(cnt,0,sizeof(cnt)); scanf("%s%d",s,&d); n=strlen(s); N=(1<<n)-1; for(int i=0;i<n;i++) cnt[s[i]-'0']++; memset(f,0,sizeof(f)); f[0][0]=1; for(int i=0;i<N;i++) for(int j=0;j<d;j++) if(f[i][j]) for(int k=0;k<n;k++) if(!((1<<k)&i)) f[i|(1<<k)][(j*10+(s[k]-'0'))%d]+=f[i][j]; int res=f[N][0]; for(int i=0;i<10;i++) res/=fac[cnt[i]]; printf("%d\n",res); } return 0; }