题目:http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1021
题意:给你一个每位都不相同的base进制数,求对它排列组合后%k等于0的种数
(xy)base % k = ( x*base+y ) % k = (( x%k ) * base + y) % k
利用这个公式,从最高位开始枚举状态,另一维枚举余数就行了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
char s[20];
int a[20];
long long dp[1<<16][20];
int main()
{
int T;
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
int base,k;
scanf("%d%d",&base,&k);
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;i++)
a[i]=s[i]>='A'?s[i]-'A'+10:s[i]-'0';
memset(dp,0,sizeof(dp));
dp[0][0]=1;
int tot=1<<len;
for(int i=0;i<tot;i++)
{
for(int j=0;j<k;j++)
{
if (!dp[i][j]) continue;
for(int l=0;l<len;l++)
{
if (i>>l&1) continue;
dp[i|1<<l][(j*base+a[l])%k]+=dp[i][j];
}
}
}
printf("Case %d: %lld\n",ca,dp[tot-1][0]);
}
return 0;
}