[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;
}

相关文章:

  • 2022-12-23
  • 2021-07-18
  • 2021-11-10
  • 2021-08-02
  • 2021-08-29
  • 2021-08-08
  • 2021-06-19
  • 2022-12-23
猜你喜欢
  • 2021-08-24
  • 2021-05-23
  • 2022-12-23
  • 2021-12-04
  • 2021-12-30
  • 2021-08-15
  • 2022-03-11
相关资源
相似解决方案