思路:很明显的数位dp,设dp[i][j] 表示选取数字的状态为i,模m等于j的数的个数,那么最后的答案就是dp[(1<<n)-1][0]。状态转移方程就是,dp[i|(1<<k)][(10*j+n[j])%m]+=dp[i][k]
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #define LL long long using namespace std; const int MAXN = 18; const int MAXM = 101; LL dp[1 << MAXN][MAXM], d = 1; int main(){ int l, m, len, c[10] = {0}; char n[20]; cin >> n >> m; l = strlen(n), len = (1 << l); dp[0][0] = 1; for(int i = 0;i < l;i ++) d *= ++c[n[i] -= '0']; for(int i = 0;i < len;i ++){ for(int j = 0;j < l;j ++){ if(i & (1 << j)) continue; if(i || n[j]){ for(int k = 0;k < m;k ++) dp[i|(1<<j)][(k*10+n[j])%m] += dp[i][k]; } } } cout << dp[len-1][0]/d << endl; }