ARC178C 题解

设值域是 \(V\),且数列 \(B\) 单调不降。为了让最大值最小,\(B_1 = 0\),此时最大值为 \(\sum \limits_{j = 1}^{L - 1} B_{j + 1} - B_j\)

把限制变一下形:

变形思路:把数列 \(B\) 放到数轴上。注意到,区间 \([B_j, B_{j + 1})\) 在和式中被加了 \(j \cdot (L - j)\) 次。

\[\begin{aligned} \sum_{j = 1}^{L - 1} \sum_{k = j + 1}^L |B_j - B_k| &= \sum_{j = 1}^{L - 1} \sum_{k = j + 1}^L B_k - B_j \\ &= \sum_{j = 1}^L j \cdot (L - j) \cdot (B_{j + 1} - B_j) \\ &= \sum_{j = 1}^{\lfloor L / 2 \rfloor} j \cdot (L - j) \cdot (B_{j + 1} - B_j + B_{L - j + 1} - B_{L - j}) \end{aligned} \]

这是一个有 \(\lfloor L / 2 \rfloor\) 个物品的完全背包,其中第 \(i\) 个物品的体积是 \(i \cdot (L - i)\)、价值是 \(1\),且总容量是 \(A_i\)

这为什么不会 TLE 呢?因为体积是 \(O(V^2)\) 的,而 \(A_i\) 只有 \(O(V)\)

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
using i64 = long long;

constexpr i64 INF = 0x3f3f3f3f3f3f3f3f;

int main()
{
    int q, n;
    cin >> q >> n;

    vector<int> query(q);

    for (auto& x : query)
        cin >> x;

    int mx = ranges::max(query);
    vector<i64> dp(mx + 1);

    for (int i = 1; i <= mx; ++i) {
        dp[i] = INF;

        for (int j = 1; i >= j * i64(n - j) && j <= (n >> 1); ++j)
            dp[i] = min(dp[i], dp[i - j * (n - j)] + 1);
    }

    for (auto x : query) {
        if (dp[x] >= INF)
            cout << "-1\n";
        else
            cout << dp[x] << '\n';
    }

    return 0;
}

时间复杂度:\(O(V \sqrt{V})\)

posted @ 2025-08-02 16:10  David9006  阅读(6)  评论(0)    收藏  举报