以为是组合,后来看着像数位dp,又不知道怎么让它不重复用。。然后就没思路 了。
其实状压就可以了 状压是可以确定一个数的使用顺序的 利用01也可以确定所有的数的使用以及不重复
dp[i+1《《e][(j*10+p[e])%m]+=dp[i][j]; 排下序去掉重复的 或者最后除去每个数出现的次数
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 LL dp[1<<18][100]; 18 int o[20]; 19 int main() 20 { 21 LL n; 22 int m,i,j,a; 23 while(cin>>n>>m) 24 { 25 memset(dp,0,sizeof(dp)); 26 LL x = n; 27 int g = 0; 28 while(x) 29 { 30 o[g++] = x%10; 31 x/=10; 32 } 33 sort(o,o+g); 34 int pp= - 1; 35 for(i = 0 ; i < g ;i++) 36 if(o[i]!=pp&&o[i]!=0) 37 { 38 dp[1<<i][o[i]%m] = 1; 39 pp = o[i]; 40 } 41 //dp[0][0] = 1; 42 //for(a = 2; a <= g ; a++) 43 //{ 44 for(i = 0 ;i < (1<<g) ; i++) 45 { 46 for(j = 0 ; j < m ;j++) 47 { 48 if(dp[i][j]) 49 { 50 int pre = -1; 51 for(int e = 0 ; e < g ;e++) 52 { 53 if(o[e]==pre) continue; 54 if(i&(1<<e)) continue; 55 if(i==0&&o[e]==0) continue; 56 dp[i+(1<<e)][(j*10+o[e])%m]+=dp[i][j]; 57 pre = o[e]; 58 } 59 60 } 61 } 62 } 63 // } 64 cout<<dp[(1<<g)-1][0]<<endl; 65 } 66 return 0; 67 }