[SCOI2007]排列

时间:2021-03-25 21:21:09

[SCOI2007]排列

看了看数据范围。。。我艹。。。爆搜可过?

等等,冷静,让我看一眼题解。。。我艹。。。真可过。。。

emm。。。再冷静分析。。。emm。。。还是写状压吧。。。

这题主要的思路就是 f[i][j] 表示 在 i 号状态下 总和%d为 j 的情况

这样我们只用判断这个方案合不合法即可。。。

对了,因为有重复数字,所以要去重。。。

呆码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int T,p[],a[],n,d,num[],f[<<][];
char ch[]; int main()
{
scanf("%d",&T);
p[]=;
for(int i=;i<=;i++) p[i]=p[i-]*i;
while(T--)
{
scanf("%s%d",ch,&d);
n=strlen(ch);
memset(num,,sizeof(num));
for(int i=;i<=n;i++)
{
num[ch[i-]-'']++;
a[i]=ch[i-]-'';
}
memset(f,,sizeof(f));
f[][]=;
for(int i=;i<(<<n);i++)
for(int j=;j<d;j++)
if(f[i][j])
for(int k=;k<=n;k++)
if((<<(k-)&i)==)
f[i|(<<(k-))][(j*+a[k])%d]+=f[i][j];
for(int i=;i<=;i++) f[(<<n)-][]/=p[num[i]];
printf("%d\n",f[(<<n)-][]);
}
}

代码