您的位置:首页 > 其它

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

2015-03-11 13:48 260 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: