题目: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 ",ca,dp[tot-1][0]); } return 0; }