bzoj1072: [SCOI2007]排列perm 压状dp
2015-01-20 12:53
351 查看
二进制位表示每一位的数字用过没有,第二维表示当前这个数%d等于几,由于有相同的数所以结尾要除以sum[I]! (0<=I<=9)
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <queue> #include <algorithm> using namespace std; int dp[1<<11][1010]; int fac[15],n,m,d,a[15],sum[15]; void getdp() { for(int i=0;i<(1<<m);i++) for(int j=0;j<d;j++) dp[i][j]=0; dp[0][0]=1; for(int i=0;i<(1<<m);i++) { for(int j=0;j<d;j++) { if(dp[i][j]==0) continue; for(int k=1;k<=m;k++) { if(! ((1<<(k-1))&i) ) { dp[ i|(1<<(k-1)) ][(a[k]+j*10)%d]+=dp[i][j]; } } } } } int main() { fac[0]=1;for(int i=1;i<=11;i++) fac[i]=fac[i-1]*i; char str[100]; int cas; scanf("%d",&cas); while(cas--) { memset(sum,0,sizeof(sum)); scanf("%s%d",str+1,&d); m=strlen(str+1); for(int i=1;i<=m;i++) { a[i]=str[i]-'0'; sum[a[i]]++; } getdp(); int ans=dp[(1<<m)-1][0]; for(int i=0;i<=9;i++) ans=ans/fac[sum[i]]; printf("%d\n",ans); } return 0; }
相关文章推荐
- bzoj1072 [SCOI2007]排列perm(状压dp)
- BZOJ 1072: [SCOI2007]排列perm 状态压缩DP
- bzoj 1072: [SCOI2007]排列perm(状压dp)
- bzoj 1072: [SCOI2007]排列perm(状压DP)
- bzoj 1072: [SCOI2007]排列perm 状压dp
- BZOJ 1072 [SCOI 2007] 排列perm (状压DP)
- BZOJ 1072 SCOI2007 排列perm 状压DP
- [BZOJ1072]-[SCOI2007]排列perm-状压DP
- [BZOJ1072][SCOI2007]排列perm(状压dp)
- [SCOI2007] BZOJ 1072 排列perm - 状压dp
- [BZOJ1072] [SCOI2007] 排列perm - dfs/dp
- BZOJ 1072 [SCOI2007]排列perm ——状压DP
- BZOJ 1072: [SCOI2007]排列perm [DP 状压 排列组合]
- [BZOJ1072][SCOI2007]排列perm(状压DP)
- [BZOJ1072][SCOI2007]排列perm(状压dp)
- BZOJ 1072 [SCOI2007]排列perm 状压DP
- BZOJ1072: [SCOI2007]排列perm 状压DP
- bzoj1072【SCOI2007】排列perm
- BZOJ 1072: [SCOI2007]排列perm
- 【SCOI2007】【BZOJ1072】排列perm