据说只要一个数的范围小就是状压DP啊

据说要整除什么数就是要记录余数来转移啊

懵逼的 题目

扯淡的 题解

翻学姐博客看见的

据说这个字符集这么小一看就是状压啊 据说这个要整除所以要记录余数转移啊

据说就做完了啊

记得用阶乘去一下重复字符的重…

沙茶的 代码

/**************************************************************
    Problem: 1072
    User: Cansult
    Language: C++
    Result: Accepted
    Time:1704 ms
    Memory:21588 kb
****************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#define LL long long
#define MAXN (2000 + 5)
#define pii pair<int, int>
using namespace std;
const int fact[10 + 5] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800};
int n, a[MAXN], d, f[MAXN][MAXN], cnt[10 + 5];
bool vis[MAXN][MAXN];
char s[10 + 5];
void init()
{
    memset(f, 0, sizeof(f));
    memset(vis, false, sizeof(vis));
    memset(cnt, 0, sizeof(cnt));
    scanf("%s", s);
    n = strlen(s);
    f[(1 << n) - 1][0] = 1;
    vis[(1 << n) - 1][0] = true;
    scanf("%d", &d);
}
void solve()
{
    queue<pii> q;
    q.push(make_pair((1 << n) - 1, 0));
    while (!q.empty())
    {
        pii dq = q.front();
        q.pop();
        for (int i = 0; i < n; i++)
            if (dq.first & (1 << i))
            {
                pii ndq = make_pair(dq.first xor (1 << i), (dq.second * 10 + s[i] - '0') % d);
                f[ndq.first][ndq.second] += f[dq.first][dq.second];
                if (!vis[ndq.first][ndq.second])
                    q.push(ndq);
                vis[ndq.first][ndq.second] = true;
            }
    }
    for (int i = 0; i < n; i++)  ++cnt[s[i] - '0'];
    for (int i = 0; i <= 9; i++)
        f[0][0] /= fact[cnt[i]];
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        init();
        solve();
        printf("%d\n", f[0][0]);
    }
    return 0;
}

By 联赛钦定爆零的 Cansult