动态规划巧解数字排列问题
题目概述
P4163 [SCOI2007] 排列是一道经典的动态规划题目,题目要求给定一个数字字符串和一个整数 $d$,计算出所有排列中能被 $d$ 整除的排列数目。数字字符串中可能包含重复数字,需要避免重复计数。
解题思路
这道题的核心在于利用动态规划和状态压缩来处理排列问题。由于数字字符串的长度最多为 10,可以使用位掩码(bitmask)来表示数字的使用情况,同时记录当前排列模 $d$ 的余数。
定义状态 $dp[mask][r]$ 表示当前使用的数字集合为 $mask$,且当前排列模 $d$ 的余数为 $r$ 时的方案数。初始状态为 $dp[0][0] = 1$,表示没有使用任何数字时余数为 0 的方案数为 1。
状态转移时,枚举所有未被使用的数字,更新新的 $mask$ 和新的余数 $r'$。新的余数可以通过公式计算: $$ r' = (r \times 10 + \text{digit}) \mod d $$ 其中 $\text{digit}$ 是当前选择的数字。
避免重复计数
由于数字字符串中可能存在重复数字,直接计算会导致重复计数。解决方法是在最后的结果中除以每个重复数字出现次数的阶乘。例如,数字 $i$ 出现了 $cnt[i]$ 次,则最终答案为: $$ \frac{dp[full_mask][0]}{\prod_{i} cnt[i]!} $$ 其中 $full_mask$ 是所有数字都被使用的状态。
代码实现
以下是基于动态规划和状态压缩的代码实现:
#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 i = 0; i < n; ++i) {
if (!(mask & (1 << i))) {
int new_mask = mask | (1 << i);
int new_r = (r * 10 + (s[i] - '0')) % d;
dp[new_mask][new_r] += dp[mask][r];
}
}
}
}
// 处理重复数字
vector<int> cnt(10, 0);
for (char c : s) cnt[c - '0']++;
int factorial = 1;
for (int i = 0; i < 10; ++i) {
for (int j = 1; j <= cnt[i]; ++j) {
factorial *= j;
}
}
cout << dp[(1 << n) - 1][0] / factorial << endl;
}
return 0;
}
优化与注意事项
- 预处理阶乘:可以预先计算阶乘值,避免重复计算。
- 状态初始化:确保初始状态 $dp[0][0] = 1$,其余状态初始化为 0。
- 位运算优化:使用位运算可以高效地枚举所有可能的数字使用状态。
- 模运算:在计算新余数时,及时取模以避免数值溢出。
复杂度分析
- 时间复杂度:$O(2^n \times d \times n)$,其中 $n$ 是数字字符串的长度,$d$ 是给定的除数。对于 $n \leq 10$,该复杂度是可接受的。
- 空间复杂度:$O(2^n \times d)$,用于存储动态规划的状态表。
总结
通过动态规划和状态压缩,可以高效地解决排列计数问题。关键在于合理设计状态转移方程,并正确处理重复数字的情况。
BbS.okapop174.sbs/PoSt/1122_314511.HtM
BbS.okapop175.sbs/PoSt/1122_145645.HtM
BbS.okapop176.sbs/PoSt/1122_632183.HtM
BbS.okapop177.sbs/PoSt/1122_545960.HtM
BbS.okapop178.sbs/PoSt/1122_900049.HtM
BbS.okapop179.sbs/PoSt/1122_543781.HtM
BbS.okapop180.sbs/PoSt/1122_968297.HtM
BbS.okapop181.sbs/PoSt/1122_178757.HtM
BbS.okapop182.sbs/PoSt/1122_841199.HtM
BbS.okapop183.sbs/PoSt/1122_177060.HtM
BbS.okapop174.sbs/PoSt/1122_850131.HtM
BbS.okapop175.sbs/PoSt/1122_017082.HtM
BbS.okapop176.sbs/PoSt/1122_449073.HtM
BbS.okapop177.sbs/PoSt/1122_991200.HtM
BbS.okapop178.sbs/PoSt/1122_837760.HtM
BbS.okapop179.sbs/PoSt/1122_605244.HtM
BbS.okapop180.sbs/PoSt/1122_624990.HtM
BbS.okapop181.sbs/PoSt/1122_748726.HtM
BbS.okapop182.sbs/PoSt/1122_065820.HtM
BbS.okapop183.sbs/PoSt/1122_683298.HtM
BbS.okapop174.sbs/PoSt/1122_326787.HtM
BbS.okapop175.sbs/PoSt/1122_596599.HtM
BbS.okapop176.sbs/PoSt/1122_929030.HtM
BbS.okapop177.sbs/PoSt/1122_995350.HtM
BbS.okapop178.sbs/PoSt/1122_126195.HtM
BbS.okapop179.sbs/PoSt/1122_842007.HtM
BbS.okapop180.sbs/PoSt/1122_767815.HtM
BbS.okapop181.sbs/PoSt/1122_841182.HtM
BbS.okapop182.sbs/PoSt/1122_149505.HtM
BbS.okapop183.sbs/PoSt/1122_160978.HtM
BbS.okapop174.sbs/PoSt/1122_084779.HtM
BbS.okapop175.sbs/PoSt/1122_808305.HtM
BbS.okapop176.sbs/PoSt/1122_857261.HtM
BbS.okapop177.sbs/PoSt/1122_245762.HtM
BbS.okapop178.sbs/PoSt/1122_322202.HtM
BbS.okapop179.sbs/PoSt/1122_500525.HtM
BbS.okapop180.sbs/PoSt/1122_824528.HtM
BbS.okapop181.sbs/PoSt/1122_260554.HtM
BbS.okapop182.sbs/PoSt/1122_522058.HtM
BbS.okapop183.sbs/PoSt/1122_799975.HtM
BbS.okapop184.sbs/PoSt/1122_505729.HtM
BbS.okapop185.sbs/PoSt/1122_601133.HtM
BbS.okapop186.sbs/PoSt/1122_536464.HtM
BbS.okapop187.sbs/PoSt/1122_856933.HtM
BbS.okapop188.sbs/PoSt/1122_583513.HtM
BbS.okapop190.sbs/PoSt/1122_976603.HtM
BbS.okapop191.sbs/PoSt/1122_621515.HtM
BbS.okapop192.sbs/PoSt/1122_047333.HtM
BbS.okapop193.sbs/PoSt/1122_567191.HtM
BbS.okapop194.sbs/PoSt/1122_878802.HtM
BbS.okapop184.sbs/PoSt/1122_594793.HtM
BbS.okapop185.sbs/PoSt/1122_840768.HtM
BbS.okapop186.sbs/PoSt/1122_900556.HtM
BbS.okapop187.sbs/PoSt/1122_290414.HtM
BbS.okapop188.sbs/PoSt/1122_467679.HtM
BbS.okapop190.sbs/PoSt/1122_953407.HtM
BbS.okapop191.sbs/PoSt/1122_240685.HtM
BbS.okapop192.sbs/PoSt/1122_896110.HtM
BbS.okapop193.sbs/PoSt/1122_213204.HtM
BbS.okapop194.sbs/PoSt/1122_695318.HtM
BbS.okapop184.sbs/PoSt/1122_642031.HtM
BbS.okapop185.sbs/PoSt/1122_996175.HtM
BbS.okapop186.sbs/PoSt/1122_751262.HtM
BbS.okapop187.sbs/PoSt/1122_636688.HtM
BbS.okapop188.sbs/PoSt/1122_856992.HtM
BbS.okapop190.sbs/PoSt/1122_619641.HtM
BbS.okapop191.sbs/PoSt/1122_515381.HtM
BbS.okapop192.sbs/PoSt/1122_750433.HtM
BbS.okapop193.sbs/PoSt/1122_949671.HtM
BbS.okapop194.sbs/PoSt/1122_213448.HtM
BbS.okapop184.sbs/PoSt/1122_940500.HtM
BbS.okapop185.sbs/PoSt/1122_288841.HtM
BbS.okapop186.sbs/PoSt/1122_819313.HtM
BbS.okapop187.sbs/PoSt/1122_966859.HtM
BbS.okapop188.sbs/PoSt/1122_576319.HtM
BbS.okapop190.sbs/PoSt/1122_497334.HtM
BbS.okapop191.sbs/PoSt/1122_200953.HtM
BbS.okapop192.sbs/PoSt/1122_565043.HtM
BbS.okapop193.sbs/PoSt/1122_876799.HtM
BbS.okapop194.sbs/PoSt/1122_562570.HtM

