signedmain() { std::cin.tie(nullptr)->sync_with_stdio(false); int n, m; std::cin >> n >> m; std::vector<int> a(n); for (auto& x : a) {std::cin >> x;} std::vector<Z> dp(m + 1); dp[0] = 1; for (int i = 0; i < n; i++) { std::vector<Z> ndp(m + 1); for (int j = 0; j <= m; j++) { for (int k = 0; k <= a[i] and j + k <= m; k++) {//枚举这种花最多能放几盆 ndp[j + k] += dp[j];//习惯正推 } } dp = ndp; } std::cout << dp[m] << '\n'; return0; }
再来看这道题,其实也是摆花(字母),但是第 (i) 种字母可以随便插入位置,(而不是像本题一样同一种只能放在同一个位置),所以方案数是前 (i - 1) 种花的方案数乘以能插入这第 (i) 种花的位置方案数,即 (\binom{n}{k}(n为当前字符串长度,k为要插入的第i种花的数量))。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
signedmain() { std::cin.tie(nullptr)->sync_with_stdio(false); int K; std::cin >> K; std::vector<Z> dp(K + 1); dp[0] = 1; for (int i = 0; i < 26; ++i) { int C; std::cin >> C; std::vector<Z> ndp(K + 1); for (int j = 0; j <= K; ++j) for (int k = 0; k <= C and j + k <= K; ++k) { ndp[j + k] += dp[j] * comb.C(j + k, k);//n = j + k } dp = ndp; } std::cout << std::accumulate(dp.begin() + 1, dp.end(), Z(0)) << '\n'; return0; }