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})\)。

浙公网安备 33010602011771号