题目链接:Codeforces 401D Roman and Numbers
题目大意:给出一个最长为18位的数n,以及小于100的数m,现在将n的各个位数重新排列,问说可以组成多少柯整除m的数,不可以有前导0.
解题思路:dp[s][j],表示说集合s下,前面剩余j的情况,有多少种可能。然后对于每种状态开一个大小为10的数组,记录下已经考虑过的数字。
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; typedef long long ll; const int N = 1<<18; const int M = 105; ll n, dp[N+5][M]; int m, c, t[N], v[N+5][M]; void init () { cin >> n >> m; c = 0; while (n) { t[c++] = n%10; n /= 10; } } ll solve (int s, int k) { if (s == 0 && k == 0) return 1; if (v[s][k]) return dp[s][k]; v[s][k] = 1; int num[10]; memset(num, 0, sizeof(num)); ll& ans = dp[s][k]; ans = 0; for (int i = 0; i < c; i++) if (s&(1<<i)) { if (num[t[i]]) continue; num[t[i]] = 1; ans += solve (s^(1<<i), (k*10+t[i])%m); } return ans; } int main () { init (); ll ans = 0; int s = (1<<c) - 1, num[10]; memset(num, 0, sizeof(num)); for (int i = 0; i < c; i++) if (t[i]) { if (num[t[i]]) continue; num[t[i]] = 1; ans += solve(s^(1<<i), t[i]%m); } cout << ans << endl; return 0; }
Codeforces 401D Roman and Numbers(记忆化搜索),布布扣,bubuko.com
Codeforces 401D Roman and Numbers(记忆化搜索)
原文:http://blog.csdn.net/keshuai19940722/article/details/21117505