Loading

CF679B 解题报告

我操,CF 彻底怒了。CF 指出了最核心的矛盾点:如果我在打题时不听音乐,怎么可能切不出来这题?这确实是我的严重错误。我需要彻底承认边打题边听音乐毫无用处,重新集中注意力。

然后这题很智慧,只需要一点点注意力就可以。

首先就是利用这个条件限制问题吧,因为题目说是贪心地放方块,于是考虑如果如果我们第一个放了 \(t\),那么之后最多只能再使用 \(\min((t+1)^3 - 1 - t^3, m - t ^ 3)\) 了。

这个东西说明:往小选未必更优。

\(a = m ^ {\frac{1}{3}}\) 向下取整。然后我们考虑,对于这个 \(m\)

  • \(a\),那么剩下的有 \(m - a ^ 3\)

  • \(a - 1\),那么剩下的有 \(\min(m - (a - 1) ^ 3, a ^ 3 - (a - 1) ^ 3 - 1) = a ^ 3 - (a - 1) ^ 3 - 1\)

  • \(a - 2\),那么剩下的有 \(\min(m - (a - 2) ^ 3, (a - 1) ^ 3 - (a - 2) ^ 3 - 1) = (a - 1) ^ 3 - (a - 2) ^ 3 - 1\)

容易注意到选 \(a - 2\) 不可能比 \(a - 1\) 更优。

\(solve(m)\) 返回目前剩余的总体积最大为 \(m\) 的所有答案二元组【使用块数,使用体积】中字典序最大的那一个。然后转移其实很简单了,目前我们只能选 \(a\)\(a - 1\),因为根据以上分析,选择更小的不可能更优。

注意到 \(m\) 的衰减其实很快,爆搜虽然会重搜节点,但是总量很小。当然你要想记忆化也行,反正时间 \(\mathcal{O}(能过)\)

也就是说还是玄学复杂度意识不够强,然后就是依旧不会搜索。然后很炸。总之就是一道比较看注意力的题目吧,多瞪一会就瞪出来了。

然后是刚好因为 Mike 在打原神,所以 In queue 一万年才过的代码。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int cb(int x){return x * x * x;}
pair<int, int> dfs(int m){
  if(!m) return {0, 0};
  int a = cbrt(m);
  pair<int, int> resa = dfs(m - cb(a));
  resa.first ++, resa.second += cb(a);
  pair<int, int> resb = dfs(cb(a) - cb(a - 1) - 1);
  resb.first ++, resb.second += cb(a - 1);
  return max(resa, resb);
}
signed main(){
  ios::sync_with_stdio(0), cin.tie(0);
  int rx; cin >> rx;
  auto [x, y] = dfs(rx);
  cout << x << " " << y << "\n";
  return 0;
}
posted @ 2026-04-26 19:38  Trent900  阅读(24)  评论(0)    收藏  举报