动态规划解决数字排列整除问题
问题描述
题目给定一个数字字符串 $s$ 和一个正整数 $d$,要求计算 $s$ 的所有排列中能被 $d$ 整除的排列数量。数字可能包含前导零,且如果数字相同但位置不同视为不同排列。
动态规划解法
使用状态压缩动态规划(DP)来解决。定义 $dp[mask][r]$ 表示当前已选数字的掩码为 $mask$,且当前数模 $d$ 的余数为 $r$ 时的方案数。
初始化时,$dp[0][0] = 1$,表示未选任何数字时余数为 0 的方案数为 1。
状态转移时,枚举每一位未选的数字 $s[j]$,更新新的余数: $$ new_r = (r \times 10 + (s[j] - '0')) \mod d $$
状态转移方程为: $$ dp[mask | (1 << j)][new_r] += dp[mask][r] $$
去重处理
如果数字中有重复字符,直接计算会导致重复计数。因此需要对结果除以重复字符的阶乘。具体来说,对于每个字符 $c$ 出现的次数 $cnt[c]$,最终答案为: $$ \frac{dp[full_mask][0]}{\prod_{c} cnt[c]!} $$
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int T;
cin >> T;
while (T--) {
string s;
int d;
cin >> s >> d;
int n = s.size();
vector<vector<int>> dp(1 << n, vector<int>(d, 0));
dp[0][0] = 1;
for (int mask = 0; mask < (1 << n); ++mask) {
for (int r = 0; r < d; ++r) {
if (dp[mask][r] == 0) continue;
for (int j = 0; j < n; ++j) {
if (!(mask & (1 << j))) {
int new_r = (r * 10 + (s[j] - '0')) % d;
dp[mask | (1 << j)][new_r] += dp[mask][r];
}
}
}
}
vector<int> cnt(10, 0);
for (char c : s) cnt[c - '0']++;
int fact = 1;
for (int x : cnt) {
for (int i = 1; i <= x; ++i) fact *= i;
}
cout << dp[(1 << n) - 1][0] / fact << endl;
}
return 0;
}
复杂度分析
时间复杂度为 $O(2^n \times n \times d)$,其中 $n$ 是字符串长度,$d$ 是给定的模数。空间复杂度为 $O(2^n \times d)$。适用于 $n \leq 10$ 的规模。
注意事项
- 数字可能包含前导零,但题目允许,因此无需特殊处理。
- 去重时需计算每个数字出现次数的阶乘,避免重复计数。
- 状态压缩 DP 通过掩码表示已选数字的位置,确保每个位置只选一次。
BbS.okacop000.info/PoSt/1120_727465.HtM
BbS.okacop001.info/PoSt/1120_924068.HtM
BbS.okacop002.info/PoSt/1120_969187.HtM
BbS.okacop003.info/PoSt/1120_162131.HtM
BbS.okacop004.info/PoSt/1120_430541.HtM
BbS.okacop005.info/PoSt/1120_491527.HtM
BbS.okacop006.info/PoSt/1120_894220.HtM
BbS.okacop007.info/PoSt/1120_505133.HtM
BbS.okacop008.info/PoSt/1120_652652.HtM
BbS.okacop009.info/PoSt/1120_463407.HtM
BbS.okacop000.info/PoSt/1120_846800.HtM
BbS.okacop001.info/PoSt/1120_982194.HtM
BbS.okacop002.info/PoSt/1120_805161.HtM
BbS.okacop003.info/PoSt/1120_926940.HtM
BbS.okacop004.info/PoSt/1120_649531.HtM
BbS.okacop005.info/PoSt/1120_930147.HtM
BbS.okacop006.info/PoSt/1120_903268.HtM
BbS.okacop007.info/PoSt/1120_180901.HtM
BbS.okacop008.info/PoSt/1120_616036.HtM
BbS.okacop009.info/PoSt/1120_981276.HtM
BbS.okacop000.info/PoSt/1120_213445.HtM
BbS.okacop001.info/PoSt/1120_783063.HtM
BbS.okacop002.info/PoSt/1120_401167.HtM
BbS.okacop003.info/PoSt/1120_996888.HtM
BbS.okacop004.info/PoSt/1120_804455.HtM
BbS.okacop005.info/PoSt/1120_909344.HtM
BbS.okacop006.info/PoSt/1120_800807.HtM
BbS.okacop007.info/PoSt/1120_885497.HtM
BbS.okacop008.info/PoSt/1120_341731.HtM
BbS.okacop009.info/PoSt/1120_265408.HtM
BbS.okacop000.info/PoSt/1120_800062.HtM
BbS.okacop001.info/PoSt/1120_180211.HtM
BbS.okacop002.info/PoSt/1120_086180.HtM
BbS.okacop003.info/PoSt/1120_069904.HtM
BbS.okacop004.info/PoSt/1120_578162.HtM
BbS.okacop005.info/PoSt/1120_826226.HtM
BbS.okacop006.info/PoSt/1120_333230.HtM
BbS.okacop007.info/PoSt/1120_655777.HtM
BbS.okacop008.info/PoSt/1120_983218.HtM
BbS.okacop009.info/PoSt/1120_508694.HtM
BbS.okacop000.info/PoSt/1120_779602.HtM
BbS.okacop001.info/PoSt/1120_751163.HtM
BbS.okacop002.info/PoSt/1120_470467.HtM
BbS.okacop003.info/PoSt/1120_288589.HtM
BbS.okacop004.info/PoSt/1120_361699.HtM
BbS.okacop005.info/PoSt/1120_879894.HtM
BbS.okacop006.info/PoSt/1120_647449.HtM
BbS.okacop007.info/PoSt/1120_195586.HtM
BbS.okacop008.info/PoSt/1120_343556.HtM
BbS.okacop009.info/PoSt/1120_997005.HtM
BbS.okacop000.info/PoSt/1120_655478.HtM
BbS.okacop001.info/PoSt/1120_453788.HtM
BbS.okacop002.info/PoSt/1120_915489.HtM
BbS.okacop003.info/PoSt/1120_310564.HtM
BbS.okacop004.info/PoSt/1120_673405.HtM
BbS.okacop005.info/PoSt/1120_997590.HtM
BbS.okacop006.info/PoSt/1120_505139.HtM
BbS.okacop007.info/PoSt/1120_662427.HtM
BbS.okacop008.info/PoSt/1120_794788.HtM
BbS.okacop009.info/PoSt/1120_580470.HtM
BbS.okacop000.info/PoSt/1120_423492.HtM
BbS.okacop001.info/PoSt/1120_529035.HtM
BbS.okacop002.info/PoSt/1120_442232.HtM
BbS.okacop003.info/PoSt/1120_935572.HtM
BbS.okacop004.info/PoSt/1120_166508.HtM
BbS.okacop005.info/PoSt/1120_535401.HtM
BbS.okacop006.info/PoSt/1120_229829.HtM
BbS.okacop007.info/PoSt/1120_845517.HtM
BbS.okacop008.info/PoSt/1120_737040.HtM
BbS.okacop009.info/PoSt/1120_856473.HtM
BbS.okacop010.info/PoSt/1120_232204.HtM
BbS.okacop011.info/PoSt/1120_146219.HtM
BbS.okacop012.info/PoSt/1120_475063.HtM
BbS.okacop013.info/PoSt/1120_656621.HtM
BbS.okacop014.info/PoSt/1120_022448.HtM
BbS.okacop015.info/PoSt/1120_422037.HtM
BbS.okacop016.info/PoSt/1120_243462.HtM
BbS.okacop017.info/PoSt/1120_035677.HtM
BbS.okacop018.info/PoSt/1120_727248.HtM
BbS.okacop019.info/PoSt/1120_486767.HtM