AtCoder Biginner Contest 258 参加記録
コンテスト中AC:A〜D
コンテスト後にEを自力AC。コンテスト中に漠然とした解法まで思い浮かんでましたが、実装間に合わず。
A〜Dは特に書くことがないので、Eについて書きます。
2022/07/08追記
Eの実装中の同値類などは誤りなので、無視してください。
E - Packing Potatoes
説明のため、じゃがいもは円環に並んでおり、番目のじゃがいもまで行ったら番目に戻るものとします。
の各について、空の状態の箱に番目のじゃがいもから箱詰めを開始したとします。この箱の箱詰めを終了し、次の箱の箱詰めを番目から開始するとします。
という関係性を有向辺とみなしてグラフ化します(この関係性は一定です)。
頂点から出発して有向辺を辿ることを繰り返すと、鳩の巣原理により高々回で1回訪問済みの頂点に辿りつき、以後ループします。
有向辺を1回辿るということと、箱詰めが1回終了したことが対応します。従って、回目の箱詰めを始めたじゃがいもの番号は、有向辺を回辿って、辿り着いた頂点番号に対応します。
回でどこの頂点番号に辿り着くかというのは、まず、ループ前の非ループ部とループ部に分けて配列に記録しておきます。非ループ部ならそのままその頂点番号を返し、ループ部に辿り着くなら、ループに属する頂点数をループのサイズとして、ループサイズでmodを取ることでで求められます。
以上から、番目のじゃがいもから始めた時に箱に詰めることになるじゃがいもの個数を予め計算しておけば、各クエリにで答えられます。
過去にもこのような構造をもつ問題は何度か出題されており、構造体Loopとして計算できるようにしてあります。
結構出題されるので、計算方法の詳細は別記事にまとめてみたいと思います。
次に、の求め方です。愚直に以上となるまで足し続けることは計算量的にできません。まずは円環で並ぶを何周するか求めます。これは、の和をとすると、周する必要があります。これをとしておきます。
残りは必要です。これをとします。残りは一周未満であることが確定します。
合計が以上となるのに残り何個のじゃがいもが必要かを求める方法としては、を2つ繋げたを用意し、累積和を求めます。
番目のじゃがいもについて、をキーとしてを二分探索することで求めることができます。 (但し、の時)
二分探索した結果、となる、が求まったとします。
すると、
となります(実装では累積和を取る時にインデックスがずれて計算がおかしくなったので、注意)。
Submission #32991116 - AtCoder Beginner Contest 258
AtCoder Biginner Contest 257 参加記録
コンテスト中AC:A〜D
コンテスト後にEを自力ACできたので、こちらに書いておきます。
2022/07/01 追記 Fも自力で解けたため追記
- C - Robot Takahashi
- D - Jumping Takahashi 2
- E - Addition and Multiplication 2
- F - Teleporter Setting
C - Robot Takahashi
誤った解法でかなり時間をロスしてました。
また、コンテスト後にこの記事を書いていて、嘘解法であることがわかりました。コンテスト中の嘘解法とコンテスト後の正しいと思われる解法書いておきます。
を大人と子供に分けます。
大人を
子供を
とします。
のいずれかが空の場合は、人達成可能です。以下、そうでない場合を考えます。
大人の判定が正しくなる個数を全探索します。この場合、実数の候補として、の要素のみを考えればよいです。
例えば、という位置にが居るとします。の範囲でを動かしても、子供の判定結果に影響を与えません。また、の範囲にすると、の判定を正しいものにできます。
よって、として、損をすることがないです(のケースで少し悩みましたが、これも問題ありませんでした)。
なお、やが存在しない場合でも、同様となります。
以上から、とした時に正しく判定できる人数をカウントします。の人数は明らかです。の人数は、を予めソートしておくことで、二分探索可能です。
コンテスト中の実装は以下のような感じです。
Submission #32731821 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)
コンテスト後に、この実装の反例が存在することがわかりました。
5
00100
10 20 30 40 50
このケースでは、実装をとして、子供の判定を全て正しくすることで、正しい判定を4人にできます。
しかし、最初の実装だと、3人になってしまいます。
なぜこのようなことになるかというと、大人の正しい判定が0人となる場合を考慮できていないためです。
これを正しく判定するためには、にを入れておけばよいです(を正しい判定となる人数に含めてはだめです)。
D - Jumping Takahashi 2
は、ある値以上ならOKで、それ未満はNGという境界があります。そこで、二分探索できないか検討します。
二分探索の判定処理にかかる見積もります。
まず、以下が言えます。
- ジャンプ力で全てのジャンプ台に到達できるかは、始点となるジャンプ台をまで全探索し、どれか1つでも達成できればよい。
次に、
- ジャンプ力、始点ですべてのジャンプ台に到達できるかは、幅優先探索によりで判定できる。
ここで、は辺数であり、今回の場合全2点間に辺がある完全グラフとみなせるため、です。よって、今回はです。
以上から、ジャンプ力で全てのジャンプ台に到達できるかという判定にかかる計算量はです。
ジャンプ力として考えられる最大をとすれば、全体の時間計算量はです。
とかでも、間に合うと想定でき、二分探索で問題ないことがわかります。
ここからが割と重要で、コンテスト中4回WAを出しました。をいい加減に大きくするとオーバーフローします。
というのも、幅優先探索で、ジャンプ台間で移動可能かの判定には問題文中の以下の式を使います。
は最大でになるため、ジャンプ力がくらいになるとがオーバーフローしてしまいます。
そこで、をしっかり目に見積もります。
と間を移動する時、
となり、右辺が最大です。また、の場合、
かどうかを判定することになるので、はを見積もれば良いことになります。実際にこれでACできました。
その他の方法としては、__builtin_smull_overflow
でオーバーフロー判定し、オーバーフローする場合は常に移動出来ることにしておいても良いかもしれません。
Submission #32746202 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)
E - Addition and Multiplication 2
10進数について、考えます。の上から桁目(の整数)をという様に表現します。
の時、以下が言えます。
- の桁数がの桁数より真に大きい
- との桁数が等しいとき、上から桁目までが等しいなら、 (但し、便宜上)
1番目の条件より、出来るだけの桁数を大きくすればよいです。そこで、支払う金額が最小の整数を選び、可能な限り置き換えを行います。なお、支払う金額が最小のものが複数ある場合、そのうち最大の整数を選びます。
次に2番目の条件より、の最上位桁から優先的により大きい整数に変更できないか検討します。変更後の整数についても大きい方から優先的に選びます。なお、の桁の2つ分を1つの別の整数に変更すると、桁数が減るので、変更は1対1で行います。
残金がなくなり、変更操作ができなくなった時のが答えです。
桁目についての具体的な変更方法は、残金をとすると、を払い戻したと考え、なら、桁目をとし、残金をと更新します。
Submission #32759248 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)
F - Teleporter Setting
町を頂点、テレポーターを辺とした無向グラフとみなします。移動時間は辺の距離とみなします。
一旦簡単のため、全て連結であるとしておきます。
に全ての未接続だった辺が繋がった場合を考えます。
最短距離は以下のパターンに限定されます。
(1) 未接続だった辺を経由しない
最短距離は、未接続だった辺を無視したの最短距離となります。
(2) 未接続だった辺を経由する
との経路に分けて考えます。最短距離は2つの最短距離の合計です。
-
から直接に行く
最短距離は未接続の辺を無視したへの最短距離となります。未接続だった辺を持つ頂点を経由してに行く
はから最も近い頂点を選びます。この時、という移動となります。最短距離は未接続だった辺を無視したへの最短距離+1です。
-
から直接に行く
最短距離は未接続だった辺を無視したへの最短距離となります。未接続だった辺を持つ頂点を経由してに行く
はから最も近い頂点を選びます。この時、という移動となります。最短距離は未接続だった辺を無視したへの最短距離+1です。
以上より、各に接続した時のからへの最短距離は、(1)又は(2)のパターンのいずれか小さい方となります。
及び未接続の辺を無視した場合の最短距離は、未接続の辺を無視したダイクストラ法を及びのそれぞれを始点として1回ずつ行えば求めることが可能です。
からに行けない時は、最短距離がになるようにすれば求めることができます。詳細は実装参照。
なお、が存在しない場合もあるので、注意が必要です(WAしました)。
Submission #32861308 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)
AtCoder Beginner Contest 256 参加記録
コンテスト中AC:A〜E
C - Filling 3x3 array
となるの組が何通りあるか考えます。これは、個の区別のないボールを横1列に並べ、個のボールの間から2つ選んで区別のない仕切りを置き、仕切りの左から順にボールの個数を整数として、に割り当てる組合わせに等しいので、通りです。
これは、について、それぞれまで全探索することで、でこれらを全て列挙できます。また、全組み合わせはのケースで通りで、かなり少ないです。
の組が少ないことがわかったので、マスへの整数の割り当てについても次から示すように全探索できます。
これから示すマスの文字は以下のようなイメージです。
a b c
x y z
p q r
1行目と2行目が確定すれば3行目も確定します。そこで、以下のような解法となります。
、となる組を全探索で列挙する。
列挙したものを
とする。
の要素の全組について、以下を調べる。について、これらの組からを計算する。
を全て満たすなら答えに+1する
の全要素の全組の全探索は、で、最大でもで、問題ありません。
実は、コンテスト中はを満たすものが何通りあるかの見積もりが間違っていました。
区別の無いボール個と、区別の無い仕切り3個を横1列に並べる通り数として計算していました。です。
これは、を満たすの組であって、それぞれ0以上の場合の通り数です。
Submission #32614557 - Tokio Marine & Nichido Fire Insurance Programming Contest 2022(AtCoder Beginner Contest 256) この解法はコンテスト後に見直したものです。
E - Takahashi's Anguish
キャンディを食べる順序を有向辺と見なせそうなので、グラフの問題で考えてみます。
また、人が人より前にキャンディを食べるというのがややこしいので、以下のように言い換えてみます。
最初の不満度はである。人の後に人がキャンディを食べると不満度は減少する。不満度の最小値を求めよ。
このように考えると、人の後に人にキャンディを食べさせて得られる不満度の減少量を最大化する問題となります。 ここでは、減少量をスコアと表現します。
人を頂点とみなし、からに向かうコストの有向辺を持つ有向グラフを考えます。
これは、出次数1の有向グラフであり、このグラフに含まれる全ての連結成分は以下を満たします。
- 閉路をただ1つ持つ
- 任意の頂点から有向辺を辿る移動を繰り返すと連結成分内の閉路にたどり着き、無限ループに入る
これは一応、当ブログのAtCoderの過去問の記事で証明してみてあります。(あまり自信はないです)
リンク (ネタバレ注意)
この有向グラフの各頂点に1回ずつ訪れることを考えると、頂点を訪問順に並べた数列をとすることができます。
訪問順を考える際、を始点とする有向辺をもつ頂点を訪問した時に、
- が未訪問なら、コストを得る(スコアに加算する)。そうでない時、得られない。
とすることで、スコアの取得条件との辻褄があいます。
スコアの上界を見積もります。
各連結成分には閉路が存在します。各閉路について、閉路に属する辺の内の1つは確実にコストを得ることができません。この得ることができないコストには各閉路で最小のものを選ぶのが最適です。
以上から、閉路に属する辺のコストの内、最小のものをとし、その和をとすると、スコアの上界はとなります。
実はこれは常に達成可能です。
これを説明するために有向グラフの連結成分の1つを考えます。
にはただ1つ閉路が存在するので、これをとします。
の部分グラフであって、という感じで閉路と接続するを考えます。
は閉路を含まないため、トポロジカル順に頂点に訪問していくことで、に属する辺及び、とを繋ぐ全ての辺(言い換えればに属する頂点を始点とする全ての有向辺)のコストを得ることができます。
に接続する全ての各部分グラフについてトポロジカル順に訪問した後、のうちコスト最小の有向辺の終点から訪問を開始し、閉路を一周すれば、閉路のコスト最小の有向辺以外のコストを全て得ることができます。
減少量(スコア)の最大値はであることが分かったので、当初の問題に戻るとから減少量の最大値を引いた値が答えなので、結果として、不満度の最小値はです。
以上より、解法は、
- 各連結成分の閉路のコスト最小をとすると、が答え
ということになります。
閉路の求め方の実装ですが、強連結成分分解を利用しました。
atcoder::scc_graph
を使うと、強連結な頂点集合が二次元配列で得られるので、列の大きさが2以上であれば閉路と見なすことができます。列の大きさが2以上の各行から最小値を得れば良いです。
Submission #32566831 - Tokio Marine & Nichido Fire Insurance Programming Contest 2022(AtCoder Beginner Contest 256)
AtCoder Beginner Contest 255 参加記録
コンテスト中AC:A
惨敗でした。コンテスト後ですが、自力でEまでは解けました。
2022/07/14 E問題の赤字部分がになっていたので、に修正
B - Light It Up
半径の2乗を二分探索します。
2乗しているのは、long doubleなどの実数だと誤差が怖いためです。
二分探索では、以下を判定基準にします。
- 全ての人がのいずれかの人が持つ明かりに照らされる
これはで全探索できますが、コンテスト中はこの判定の実装が間違っていました。
の上限として、を見積もっても、十分余裕がありました(厳密にはくらい?)。
最後に2乗根をとって答えとします。
https://atcoder.jp/contests/abc255/submissions/32422863
C - ±1 Operation 1
等差数列とします。
は、の最も近い要素にするのが最適です。
値の大小順にをに挿入すると以下の3通りが考えられます。
それぞれのケースの答えは、
です。
1,3のケースは簡単に求められます。問題は2のケースですが、これは二分探索により求められます。
コンテスト中はのケースが抜けていました。
Submission #32422643 - Aising Programming Contest 2022(AtCoder Beginner Contest 255)
D - ±1 Operation 2
例えば、の未満の要素がであったとします。
これをにしたい時にかかる操作回数は、
式変形すると、
となり、とすると、
となります。
同様に、より大きいの要素をとすると、必要な操作回数は、
となります。
余談ですが、式は説明のために書きましたが、コンテスト中は棒グラフを書いて、で線を引く感じをイメージしました。
解法ですが、未満とより大きい要素の和を効率よく得られればよいです。の順序は無視できるため、を昇順ソートして、累積和を計算しておくと、二分探索して和を得られます。
具体的には以下のようになります。
- を昇順ソートする
- の累積和を得る
- 各クエリについて、以下を行う
- 二分探索で、ソート済みのの要素の内未満の最大値と、より大きい要素の最小値を得る。
- を出力する
なお、が存在しない場合の例外処理が必要です。
コンテスト中はクエリの処理部分を以下のようにしていました。
以上の最小値を二分探索で得る(lower_bound)。
を出力する
とに分けるような方法です。
この実装は、にが存在すれば、おそらく問題なく動作すると思うのですが、そうで無い場合、例えば以下のようなケースで答えがおかしくなります。
1,5を3にするのにそれぞれ2回の操作が必要なので、計4回となるはずです。しかし、上記の実装だと、となり、となってしまいます。
おそらくを大きい方の和に入れておけばよかったです。つまり、
と
という風に分けておけばよかったものと思います。
Submission #32420079 - Aising Programming Contest 2022(AtCoder Beginner Contest 255)
E - Lucky Numbers
コンテスト後に解きましたが、思わぬところでTLEになり解決に時間がかかりました。
はとで表現できます(便宜上、とします)。具体例を示すと、
という感じです。
ここで、定数部分をとします。
そうすると、は以下のように表現できます。
が偶数の時、
が奇数の時、
また、は、以下の漸化式で計算できます。
ここまでで前準備が終了です。
少なくとも1つはラッキーナンバーにしないと損をするので、がそれぞれ、である時のラッキーナンバーの数を全探索します。
である時を考えます。
は以下のように計算できます。
が偶数の時
が奇数の時
が求まると、がラッキーナンバーとなるためのが満たすべき条件がわかります。すなわち、
が偶数の時
が奇数の時
従って、予めについて、偶奇を分けてハッシュマップに個数をカウントしておけば、上記を満たすようなものの個数をで得られます。
のときに、となるものがあるかをで調べられるので、時間計算量はとなり、問題ないと思われました。
しかし、実装時C++のunoredered_mapでこれを実装するとTLEになりました。
結局、とその個数をpairにしたvectorを昇順ソートし、lower_boundすることでACしました。
Submission #32478157 - Aising Programming Contest 2022(AtCoder Beginner Contest 255)
AtCoder Beginner Contest 254
コンテスト中AC:A〜C,E
AtCoder Beginner Contest 254 - AtCoder
解けなかったDを解説見てACしたので少しだけ付け足しして書いておきます。
D - Together Square
この問題では、以下の命題が重要そうです。
厳密な証明までは必要なさそうですが、一応理解を深めるため、ここでは証明しておきます。(素人なので、間違っていたらすみません)
まず、以下の補題を証明します。
整数が平方数である任意の素数について、に含まれるの個数が偶数
[証明]
[ ]は平方数であるから、を満たす整数が存在する。の素因数分解をとすると、
となり、示された。
[ ]
の素因数分解をとすると、は偶数なので、
を満たす整数が存在し、先程と同様な議論でとなるため、は平方数である。
では、元の命題を証明してみます。
[証明]
[ ]対偶を示す。
ある素数について、に含まれる個数の偶奇が等しくないとする。
偶数個であるものを、奇数個であるものをとおく。
に含まれるの個数に着目すると、
となり、は奇数個となる。補題より、は平方数では無い。よって、対偶が示された。
[ ]任意の素数について、に含まれる個数が共に偶数個である場合、それぞれとすると、に含まれる個数もとなり偶数である。共に奇数個である場合とすると、となり偶数となる。よって、偶奇が等しい場合に含まれる任意の素数の個数は偶数個となり、補題よりは平方数である。
証明は以上です。
ここまでで、が平方数となるためには、の素因数の個数の偶奇が等しい必要があることがわかりました。
次に、そのような組の求め方です。
の素因数の内、奇数個である素因数の1乗の積を考えます。
なら、
なら、
です。
は素数の1乗の積なので、含まれる素数に対して一意に定まることから、素数の偶奇の状態に対しても一意に定まります。
そのため、ならの素因数の偶奇の状態が等しいと判断できます。
以上から、以下の解法が導かれます。
- について、を求め、同一なの個数をカウントする
- の個数をとすると、を全てのについて計算し、総和をとったものが答え
これが公式解説の解法です。(この記事では、を別物として定義しています。)
の求め方ですが、公式解説やユーザ解説に色々方法がありますが、こちらのユーザ解説で実装してみました。線形篩を知らなかったので、勉強になりました。
Submission #32343255 - AtCoder Beginner Contest 254
AtCoder Biginner Contest 253 参加記録
コンテスト中AC:A〜E
NOMURA Programming Contest 2022(AtCoder Beginner Contest 253) - AtCoder
B - Distance Between Tokens
マンハッタン距離に関する問題です。
'o'
である2箇所をとすれば、答えは、
です。
Submission #32006932 - NOMURA Programming Contest 2022(AtCoder Beginner Contest 253)
C - Max - Min Query
多重集合をC++の多重集合multiset
で解けます。
実装は後ほど記載のリンク参照。
WAを出したのですが、S.erase(i)
をS.erase(x)
にしてしまってあり、こうするとS
の中のx
が全て削除されてしまいます。
補足ですが、S
に追加される個数が高々個なので、削除される回数も全体で高々回です。
Submission #32020504 - NOMURA Programming Contest 2022(AtCoder Beginner Contest 253)
D - FizzBuzz Sum Hard
基本的な包除原理です。
からまでの全体の和から不要なものを引くことを考えます。
までのの倍数であるの和をとおきます。
とすると、の倍数かつの倍数であるものを余分に1回引いてしまっています。
そこで、までのの倍数かつの倍数であるの和をとおきます。
すると、で答えを求められます。
の倍数かつの倍数であるは、との最小公倍数をとして、の倍数となります。よって、を求めればよいです。
具体的な計算方法です。
まず、は、です。
は以下のように求められます。
に含まれるの倍数の個数をとします。は下式により求まります。
求めたいものは
なので、
で求められます。
Submission #32025795 - NOMURA Programming Contest 2022(AtCoder Beginner Contest 253)
E - Distance Sequence
としてあり得るのはなので、数列の状態数は、個であり、DPできそうです。
数列の番目がであるような数列の個数
このテーブルをの順に更新していくことを考えます。
遷移は、問題文の条件を考えると、
という感じになります(後の説明のために()で括ってあります)。
愚直に1個ずつ足していくと遷移に時間計算量かかり、全体でとなり、間に合いません。
そこで、遷移にかかる計算量を落とせないか考えてみます。
すると、
及び
は連続した区間の和となっています。
このような場合、累積和によって、計算量を落とせます。
具体的には、
とします。但し、便宜上としておきます。
このようにすると、先程の遷移の右辺は、
という風になり、で計算できるようになります。
実装時、いくつか気をつける点があります。
となる可能性があるので、をとる。
となる可能性があるので、をとる。
更に、上記2つでそのまま実装すると、の時にコーナーケースとなります(が2回足されてしまうはず)。
そのため、
- のときは、遷移をとする。
このようにしておけばよいです。
Submission #32041363 - NOMURA Programming Contest 2022(AtCoder Beginner Contest 253)
AtCoder Beginner Contest 252 参加記録
コンテスト中AC: A〜F
C - Slot Strategy
解法は公式解説と同じだったので、実装例だけ書いておきます。
の左から番目に文字があるとして、を配列に記録しておきます。これを、
とします。
これを昇順ソートして、ランレングス圧縮すると、文字が何番目に何個出現するかという組が得られるので、あとは公式解説の方法で計算できます。
Submission #31861075 - AtCoder Beginner Contest 252
D - Distinct Trio
"3つがすべて異なる"は、"2つ以上同じものが存在することの補集合"と捉えられます。
そこで、各整数について、ちょうど2個同じ場合とちょうど3個同じ場合の総和を求め、3つを選ぶ総数から引くことにします。
なお、重複なく選ぶことを前提とします。
では、その求め方です。
ここで、を整数の出現数とします。
整数がちょうど2個同じ
である必要があります。
を2個選ぶ組み合わせは通りです。
残り1つは以外ならなんでも良いので、通りです。
よって、通りです。整数をちょうど3つ選ぶ
である必要があります。
整数から3つ選ぶ組み合わせなので、です。全体から3つを選ぶ総数
となります。
3から、各整数についての1,2の総和を引けば答えとなります。
時間計算量は、かなと思います。なお、はに含まれる整数の最大値です。
E - Road Reduction
が、都市1から各都市への最短路であれば、条件を満たすことができます。
辺のコストが非負整数なので、ダイクストラ法で最短経路を求められます。ダイクストラ法で最短路に使用する辺がわかるので、これを残しておけば、そのまま問題の答えになります。
この方法によって、もう一つの答えの条件である辺が個になる、すなわち木になるかどうかについてですが、コンテスト中は、閉路はできないだろう、と直感的に解いてしまい、考察が不十分だったので、もう少ししっかり考えてみます。
説明1
ダイクストラ法の各段階において。最短路が見つかっている頂点集合を、見つかっていない頂点集合をとします。
ここから、のある頂点の最短路が決定するとします。
もし、に含まれる頂点がと辺で繋がっていたとしてもその中から最短路として選ばれるのはただ1つです。 よって、との任意の辺を繋いで閉路ができることはないです。
また、に含まれるもの同士で繋がることもあり得ません。
以上より、ダイクストラ法の各段階で、閉路が生成されることはないので、最終的に出来上がるものは木になります。
説明2
以下を証明してみます。
無向グラフにダイクストラ法を適用し、始点からの最短路を見つける。ダイクストラ法の各段階において、からの最短路が見つかっている頂点数が個であるとき、この頂点集合をとおく。また、に含まれる任意の頂点への最短路を構成する辺集合をとする。
からなる、の部分グラフは常に木であることを示す。なお、木であるとは、以下が成り立つことである。
- は連結
のとき、にはのみが存在し、連結です。より、を満たします。
のときに成り立つと仮定します。
ダイクストラ法によって、に含まれるある頂点の最短路が決定されるとします。
この時、最短路決定に使用された辺が存在します。なお、頂点はに含まれる頂点の1つです。
に、にがそれぞれ追加されたものがとなります。
まず、仮定よりは連結です。また、新たに追加されたはと連結なので、は連結です。
次に、、です。仮定より、が成り立っているので、代入することでが得られます。
以上で、帰納法によって、は常に木であることが示せたと思います。
Submission #31869657 - AtCoder Beginner Contest 252
F - Bread
解法は公式解説と同じでした。
公式解説のように解法の正当性を厳密に証明できませんでしたが、コンテスト中に大雑把に考えていたことを書きます。
操作の逆を考えたとき、長さと長さのパンから長さのパンを得ることを合体と呼ぶことにします。
まず、入力例1からどのように操作すると解が悪化するのか考えました。
例えば、
2+2=4
4+1=5
5+1=6
7+1=7
とすると、解は4+5+6+7=22になり、16より悪化します。
これより、大きい数に合体していくと解は悪くなりそうだとわかりました。ということは、逆に小さいものを2つ選んで合体していけばよいだろうと考えました。
次に、小さいものを2つ選んで合体すると、その後の解に影響を与えるか考えてみました。例えば、入力例1で、最初に1と1を合体した場合と1と2を合体した場合を考えます。
この操作によって、2と3のいずれかが生成されるわけですが、2や3はまた更に合体しないといけないので、追加で2または3のコストがかかります。それなら、1と1を合体したほうがよいです。
こんな感じでしたが、一応ACはできました。
Submission #31875956 - AtCoder Beginner Contest 252