BZOJ 1072 [SCOI 2007] 排列perm (状压DP)

来源:互联网 发布:手机淘宝怎么关注品牌 编辑:程序博客网 时间:2024/05/17 21:50

题目链接:BZOJ 1072

dp[i][j]:i表示每个数选与不选的状态,j表示当前状态的余数

#include<cstdio>#include<cstring>#include<iostream>using namespace std;int a[20],num[20],p[20],dp[1025][1005];int main(){freopen("test.in","r",stdin);freopen("test.out","w",stdout);int T,N; scanf("%d",&T);char s[20];while(T--){memset(dp,0,sizeof(dp));scanf("%s",s+1); scanf("%d",&N);int L=strlen(s+1);for(int i=0;i<=9;i++)p[i]=1, num[i]=0;for(int i=1;i<=L;i++){a[i]=s[i]-'0'; num[a[i]]++;p[a[i]]*=num[a[i]];}dp[0][0]=1;for(int i=0;i<(1<<L);i++){for(int j=0;j<N;j++){for(int k=0;k<L;k++){if(!(i&(1<<k))){dp[i|(1<<k)][(a[k+1]+j*10)%N]+=dp[i][j];}}}}for(int i=0;i<=9;i++){dp[(1<<L)-1][0]/=p[i];}printf("%d\n",dp[(1<<L)-1][0]);}return 0;}


0 0