よい集合全体を列挙することは到底できないから,その必要がない形に言い換えたい.
よい集合全体をG, 必要なカードの集合をNeedとする.以下カードiを書かれている値a[i]と同一視する.
部分点解法(editorial+α)
問題文より:
i∈/Need⟺i∈∀s∈G s.t. s∖{i}∈G
である.先の要請から∀を消すために対偶を取ると:
i∈Need⟺i∈∃s∈G s.t. s∖{i}∈/G.
ところでs∈Gとは∑s≥Kのことであった.このようにカードの数に関する形に言い換えてみると:
i∈Need⟺i∈∃s,∑s≥K s.t. ∑s−i<K
すなわちK≤∑s<K+iかつiを含む集合sが存在すればiが必要であることが分かる.
このような集合sが存在するか知りたい.「総和が範囲内であるような集合が存在するか」はdp[v]=(総和がvの集合が存在するか)のようなdp配列を更新する過程で求まる.すなわち行うdpは初期値dp[i]=true,状態O(K)(∵K+i以上は考えなくてよい),遷移O(N)(∵i枚目以外の任意のカードjに対し,dp配列の値がある箇所dp[v]についてdp[v+j]←trueとする)となる.これをすべてのiに対して繰り返すから,計算量はO(N2K)となって部分点解法が得られる.
このdpができることはeditorialを見るまで気付けなかったのだが,集合(の構成過程)を状態と見れば,総和が等しい状態を纏めて考えることができる,というような考え方でよいのだろうか.
追記(2019/03/09): DPの資料を漁っていたら部分和問題と言うものが載っていた.これは総和がある値であるかの判定問題だが,今回のように範囲内か否かも同様のDPで可能.ちなみにKが大きかったら半分全列挙をすればO(2N/2)らしい.
満点解法: 二分探索(editorial)
カードi≤jについてiが必要ならばjも必要であることを示す:再掲するが,
i∈Need⟺i∈∃s s.t. K≤∑s<K+i
であった.いまiが必要とするとこのようなsが存在するはずである.sの候補は(1)jを含むか(2)jを含まないかに二分される.
(1)の場合∑s<K+iから∑s−j≤∑s−i<K.よってK≤∑s<K+jであるからjも必要であることが言える.
(2)の場合ではsからiを除いてjを加えた集合tを考えてみると,K≤K−i+j≤∑s−i+j<K+jであるからtはK≤∑t<K+jを満たす(∵ ∑t=∑s−i+j).従ってjを必要たらしめる集合tが構成できるからjも必要.
よって必要である最小のカードを見付ければ,それ以上のカードはすべて必要であり,それ未満のカードはすべて不要となる(対偶).従って単調性から二分探索が可能. 解答例
嘘解法と別解
数か月前に解こうと思ったときに参照したところ嘘解法(テストケースの不足から提出すればACとなるが,実際には誤りである解法という意味の競プロ用語)だった記事があり,そこから正解法にできないかと考えた記録.
嘘解法の概略:書いてある数字の大きいほうからカードを読んで和uを記録する.u≥Kになればuを構成する数は必要最小限でよい集合を為すから,それ以外の数はそこまでの過程では不要になる.よってそこの番地ansを記録しておけば,最終的にansから右がすべて不要な数と分かる.u<Kであればuにカードの数を加算する.
これはすなわち「その構成要素だけでは良い集合たりえないが,加えるa[i]によっては良い集合になるような候補」のうち最適,すなわちKとの差が最も小さいものをuが表せているという信念に基づいている.
ところが例えばK=26, a={18,10,9,7}
を考える.3番目まで見たときu=a[1]=18であるが,このとき実際に最もKに近い候補は集合V={a[2],a[3]}={10,9}の総和19であってuではない.ここでa[4]を採用するとき,元のuだとu+7=25<Kとなり7は不必要なカードとなってしまう一方,Vの場合では集合{a[2],a[3],a[4]}={10,9,7}の総和は19+7=26=Kとなり正しく7が必要なカードと判定される.このような理由からこれは誤った解法である.
さて実際にuとして持っておきたいのは,Kとの差が最も小さい候補であった.反例で見たように逆転が起こるから実際にこれだけを持つことは無理そう.よって先の部分点解にあるdp配列(=すべての候補)を更新することになるが,これでも各iに相当する処理が不要なのでO(NK)で済む. 解答例
解法の正当性を言いたい.以下wとしたときはdp[w]=trueである,すなわちw<Kが総和となる数の集合Swが存在するものに限るとする.
いま新たにカードvを考える.あるwに対してw+v≥Kとなる場合,カードを降順に見ていったことから,Sw+v(Sw+v自体は複数あり得るがそのうちvを含むものとする)は「必要最小限なよい集合」,すなわちこれに含まれるどの数字を除いてもよい集合ではなくなる(∵ 降順より∀i∈Swについてv≤iであり,またvの必要性からK≤∑Sw+v<K+vであるから,∑Sw+v−i<K+v−i≤K.ゆえに集合S′:=Sw+v∖{i}は∑S′<Kであるからよい集合に属さない).したがってSw+vに含まれるすべてのカードは必要である.一方でwが存在しない場合はvは(現時点では)不要である.
いまvが必要になったとする.vの前に不必要と判定されたカードuがあるとき,uは必要となるかを考えたい(満点解法の説明にもあるが現在の記法で再度説明する).ここでvを必要たらしめたSwを考える.ここにuが含まれていればSwの最小性からuも必要となる.一方でそうでない場合を考えたいが,このとき降順から∑Sw+u=∑Sw+u≥∑Sw+v≥Kであり,また∑Sw<Kであったから∑Sw+u<K+u.これらからK≤∑Sw+u<K+u,すなわちuについてもSwで必要とできることが分かるから,これはあり得ない.
従ってvが必要と判明したとき,それまでの全カードが必要であることが分かる.よってvがi番目のカードのときans←iとし,最終的にans番目より右側のカード,すなわちn−ans枚が不要とすればよい.
テストケースを様々な範囲で計5000個ほど生成して先のeditorial解と出力を比較してみたところすべて等しかったので,きっと正しい解法になったはず.