Http://codeforces.com/problemset/problem/401/D
Given a number N, each digit of N is rearranged to find the number of methods in which N can be divisible.
Solution:
Brute force timeout ......
Most people write bit compression, but that would require 2 ^ 18*100 space, low efficiency, a large number of duplicate states, and inconvenient to process, this question provides a space of MB. However, if the space is doubled, the former method will be powerless.
It is found that there is a better state compression method for digital DP, which is directly compressed according to the number of times that digital X appears. For example, 333444 requires 2 ^ 6 = 64 space for compression using the former method, and only 3*3 space for Compression Based on the number of occurrences. For extreme data, by using the mean inequality, we only need (Ceil (18/10 + 1) ^ 10) = 59049 space, which improves the space utilization (Originally 2 ^ 18 = 262144) and the efficiency of heavy judgment.
The DP equation also easily establishes a part of the following State for all the numbers that require n to take the remainder of J for encoding I plus 10 plus the next digit. The result is that the remainder of all numbers is 0 (DP [s] [N]).
The key to this compression is codeit and decode functions.
Code
#include <cstdio>#include <cstring>#include <cmath>#include <map>#define SIZES 40000using namespace std;char n[20];int c[10],d[10],tim[10],m;long long dp[60000][100];int len;int codeit(int *te){ int res=0; for (int i=0;i<10;i++) res=res*(tim[i]+1)+te[i]; return res;}long long decode(int l,int *t){ for (int i=9;i>=0;i--){ t[i]=(l%(tim[i]+1)); l/=(tim[i]+1); }}int main(){ int s; while(~scanf("%s%I64d",n,&m)){ memset(dp,0,sizeof dp); len=strlen(n); memset(tim,0,sizeof(tim)); for (int i=0;i<len;i++) ++tim[n[i]-'0']; int s=codeit(tim);// printf("%d\n",s); dp[0][0]=1; for (int i=0;i<s;i++){ int t[10]; decode(i,t); for (int j=0;j<10;j++) if (i+j) if (tim[j]-t[j]){ t[j]++; int pt=codeit(t); for (int k=0;k<m;k++) dp[pt][(k*10+j)%m]+=dp[i][k]; t[j]--; } } printf("%I64d\n",dp[s][0]); }}