[CF401D] Roman and Numbers

[CF401D] Roman and Numbers - 状压dp

Description

将n(n<=10^18)的各位数字重新排列(不允许有前导零) 求 可以构造几个mod m等于0的数字

Solution

状压 dp,从高位往低位走,枚举下一位选哪个数字,设 (f[s][k]) 表示选取了 s 子集的数字,余数为 k

#include <bits/stdc++.h>
using namespace std;

#define int long long
int f[1 << 18][105], n, a[19], cnt[10], m;

signed main()
{
    ios::sync_with_stdio(false);
    string str;
    cin >> str;
    int len = str.length();
    for (int i = 0; i < len; i++)
        a[i] = str[i] - '0';
    cin >> m;
    f[0][0] = 1;
    for (int i = 0; i < 1 << len; i++)
        for (int j = 0; j < len; j++)
            if ((i & (1 << j)) == 0 && (i > 0 || a[j] > 0))
            {
                for (int k = 0; k < m; k++)
                    f[i | (1 << j)][(k * 10 + a[j]) % m] += f[i][k];
            }
    int ans = 1;
    for (int i = 0; i < len; i++)
        ans *= ++cnt[a[i]];
    cout << f[(1 << len) - 1][0] / ans << endl;
}
原文地址:https://www.cnblogs.com/mollnn/p/14479816.html