您的位置:首页 > 其它

[bzoj1072][SCOI2007]排列(状态压缩DP)

2014-09-14 11:55 288 查看
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1072

分析:看了题解才知道,状态的设计很巧妙,用余数表示,即f[i][j]表示二进制状态i下余数为j的方案数,然后列一列式子就可以了,注意排除相同数字的情况。

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
using namespace std;
const int maxn=1024;
int f[maxn+50][1000];
char s[15];
int t,d;
int main()
{
scanf("%d\n",&t);
while(t)
{
--t;
scanf("%s%d\n",s,&d);
int n=strlen(s);
memset(f,0,sizeof(f));
int m=(1<<n) - 1;
for(int i=0;i<n;++i) f[1<<i][(s[i]-48)%d]=1;
for(int i=1;i<=m;++i)
for(int j=0;j<n;++j)
if((i&(1<<j))!= 0 && i-(1<<j)>=0)
for(int k=0;k<d;++k)
f[i][(10*k+(s[j]-48))%d]+=f[i-(1<<j)][k];
for(int i=0;i<=9;++i)
{
int ans=0;
for(int j=0;j<n;++j)
if(s[j]-48==i) ++ans;
int c=1;
for(int j=2;j<=ans;++j) c*=j;
f[m][0]/=c;
}
printf("%d\n",f[m][0]);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: