[背包] LOJ#6089. 小 Y 的背包计数问题

\(\texttt{link}\)

考虑根号分治:

  • \(i\le \sqrt n\):做多重背包,可以先做完全背包,再 \(f_j-=f_{j-i(i+1)}\) 减掉不合法的。

  • \(i > \sqrt n\):每种物品可以看作有无限个,做完全背包,但是直接做还是 \(\mathrm{O(n^2)}\) 的。

    类似 \(ARC107D\),考虑记 \(dp(i,j)\) 为选了 \(i\) 个物品,总体积为 \(j\) 的方案数,有两种决策:

    • 添加一个体积为 \(\sqrt n + 1\) 的物品, 即 \(dp(i+1,j+\sqrt n + 1) += dp(i,j)\);

    • 给已选的 \(i\ge 1\) 个物品体积均加 \(1\) , 即 \(dp(i,j+i)+=dp(i,j)\) 。

    可以证明这种方式可以构造出所有合法方案。

总时间复杂度 \(\mathrm{O(n\sqrt n)}\) 。

\(\texttt{Code:}\)

#include <bits/stdc++.h>
#define pb push_back
#define _pr pair<int, int>
#define mp make_pair
#define fi first
#define se second
#define ll long long
using namespace std;
namespace _MoFa {
    const int cmd = 23333333;
    int _add(int a, int b) {a += b; return a < cmd ? a : a - cmd;}
    int _sub(int a, int b) {a -= b; return a < 0 ? a + cmd : a;};
    int _mul(int a, int b) {return 1ll * a * b % cmd;}
    int fpow(int a, int b) {
        int res = 1;
        for (; b; b >>= 1, a = _mul(a, a))
            if (b & 1) res = _mul(res, a);
        return res;
    }
}using namespace _MoFa;
inline int read() {
    int x = 0, f = 0; char c = getchar();
    while (!isdigit(c)) f |= c == '-', c = getchar();
    while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
    return f ? -x : x;
}
const int maxn = 1e5 + 5;
int n, f[maxn], g[320][maxn];
int main() {
    n = read();
    int B = sqrt(n);
    f[0] = 1;
    for (int i = 1; i <= B; i++) {
        for (int j = i; j <= n; j++) f[j] = _add(f[j], f[j - i]);
        for (int j = n; j >= i * (i + 1); j--)
            f[j] = _sub(f[j], f[j - i * (i + 1)]);
    }
    g[0][0] = 1;
    for (int i = 0; i <= B; i++)
    for (int j = 0; j <= n; j++) {
        if (j + B + 1 <= n) g[i + 1][j + B + 1] = _add(g[i + 1][j + B + 1], g[i][j]);
        if (i && j + i <= n) g[i][j + i] = _add(g[i][j + i], g[i][j]);
    }
    int ans = 0;
    for (int i = 0; i <= n; i++)
    for (int j = 0; j <= B; j++)
        ans = _add(ans, _mul(f[i], g[j][n - i]));
    printf("%d", ans);
    return 0;
}
上一篇:SpringCloudAlibaba(十)——sentinel组件的熔断降级和热点规则


下一篇:SpringCloudAlibaba的探索之旅——SpringCloud整合Sentinel