AtCoder Talent Quest 〜 今から28卒には脱出してもらいます〜予選 #2(AtCoder Beginner Contest 480)E,F問題メモ

AtCoder Talent Quest 〜 今から28卒には脱出してもらいます〜予選 #2(AtCoder Beginner Contest 480)

序盤からそこそこ難しい(手で解くのはできるけど、どう楽に実装に落とし込もうか?を迷う)問題が揃っていた印象。

E - Product-Bounded Arithmetic Sequences

問題文

  • 以下の条件を全て満たす正整数列 $A=(A_1,\dots,A_{|A|})$ を良い数列と定めます。
    • $|A|\geq 3$
    • $A$ は等差数列である。即ち、全ての $1 \leq i \leq |A|-1$ について $A_{i+1}-A_{i}=A_2-A_1$
    • $A_2-A_1 \gt 0$
  • 良い数列のうち、要素の総積が $N$ 以下であるものの個数を求めてください。
  • なお、制約の条件下で答えが $10^{18}$ 以下となることが証明されます。

制約

  • $1 \leq N \leq 10^{18}$
  • $N$ は整数

解法

初項 $a$、交差 $d$、項数 $m$ の3つの要素を決めれば総積が決まる。

それぞれ、他の2つが最小であるときに取り得る値の範囲を考えると、(大体のオーダーで)

  • $1 \le a \le 10^6$
  • $1 \le d \le 10^9$
  • $3 \le m \le 19$

よって、$(a, m)$ を全探索し、その中で $d$ をどこまで大きくできるか二分探索すればよい。

Python3

F - Cake Cutting

問題文

  • $N$ 個のケーキがあり、 $i$ 個目のケーキの大きさは $A_i$ です。これらのケーキを $M$ 人に配ろうとしています。
  • ケーキの大きさの総和 $A_1+\dots+A_N$ を $S$ とします。 ここで、 $S$ は $M$ の倍数であることが保証されます。
  • あなたは、以下の操作を好きな順序で好きな回数( $0$ 回でもよい)行うことができます。
    • ケーキを $1$ つ選び、それを自由に $2$ つに切り分ける。
    • 切り分ける大きさは整数でなくてもよく、1つのケーキを何回切ってもよい。
  • 操作後、ケーキを $M$ 人に配ります。どの人がもらうケーキの大きさの合計も $\frac{S}{M}$ となるようにするための、操作回数の最小値を求めてください。

制約

  • $1 \leq N \leq 20$
  • $1 \leq M \leq 100$
  • $1 \leq A_i \leq 10^9$
  • $A_1+\dots+A_N$ は $M$ の倍数
  • 与えられる数値は全て整数

解法

次のように言い換えてイメージする。

  • 長さ $A_1,A_2,...,A_N$ の棒を一列に並べて、左から $\frac{S}{M}$ の位置ごとに切っていく。

これで、多くとも必ず $M-1$ 回の操作で達成できることが分かる。
切ろうとしている位置が元から切れていた(棒の境界だった)場合、1箇所ごとに1回、操作回数を節約できる。

$A$ を適切に並べ替えることで、$\frac{S}{M}$ の倍数位置に境界が来る回数を最大にすればよい。

  • $\mathrm{DP}[S]:=$ 集合 $S$ を適切に並べ替えることで $\frac{S}{M}$ の倍数位置に境界を作ることができる最大回数

(末尾も境界とした上で)$M-\mathrm{DP}[A]$ が答えとなる。

DPは、$S$ にまだ存在してない適当な1つを加えて $\frac{S}{M}$ の倍数になるなら $\mathrm{DP}[S | i] ← \mathrm{DP}[S]+1$ としていく遷移で、$O(N2^N)$ で解ける。

Python3

programming_algorithm/contest_history/atcoder/2026/1017_abc480.txt · 最終更新: by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0