ABC 431
Table of Contents
https://atcoder.jp/contests/abc431
A. Robot Balance
https://atcoder.jp/contests/abc431/tasks/abc431_a
B. Robot Weight
https://atcoder.jp/contests/abc431/tasks/abc431_b
C. Robot Factory
https://atcoder.jp/contests/abc431/tasks/abc431_c
D. Robot Customize
https://atcoder.jp/contests/abc431/tasks/abc431_d
すべてのパーツを体につけることはできるので嬉しさは $\sum_i B_i$ 以上であることが言える。
すべてのパーツを体につけたあとにいくつかを頭に付け替えることで嬉しさを最大化させたい。 例えば $i$ 番目のパーツを頭に付け替えると、嬉しさは $H_i - B_i$ 変化する。
$V_i = H_i - B_i$ とし、重さの和が $w$ のときの $V_i$ の和の最大値を dp を使って求める。
$w \leq \frac{\sum_i W_i}{2}$ を満たす$w$ について、$dp[w] + \sum_i B_i$ の最大値が答えとなる。
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vll W(N), H(N), B(N);
rep(i, N) cin >> W[i] >> H[i] >> B[i];
ll sumb = accumulate(all(B), 0ll);
ll sumw = accumulate(all(W), 0ll);
vll dp(500 * 500 + 5, -INF);
dp[0] = 0;
rep(k, N) {
ll w = W[k], h = H[k], b = B[k];
for (ll i = 500 * 500; i > 0; i--) {
if (i - w < 0) continue;
if (dp[i - w] == -INF) continue;
chmax(dp[i], dp[i - w] + h - b);
}
}
ll ans = sumb;
rep(w, sumw / 2 + 1) {
chmax(ans, dp[w] + sumb);
}
cout << ans << endl;
}
$H_i \leq B_i$ であればそのパーツは頭につけるメリットはないので体につけるとしてよいので DP をするときもそれらのパーツは考慮しなくても良いけど、入れても問題ない。
E. Reflection on Grid
https://atcoder.jp/contests/abc431/tasks/abc431_e
解説で書かれていることの方針で行こうと思ったが鏡に対して2回反射するケースでダブルカウントしてしてしまって解けないと思ったが公式の解説補足にそのケースでも問題ないことが書かれていた。 問題ないことの証明も書かれていたが長かったので読んでいない。
https://atcoder.jp/contests/abc431/editorial/14511
https://atcoder.jp/contests/abc431/editorial/14552
F. Almost Sorted 2
https://atcoder.jp/contests/abc431/tasks/abc431_f