{'b': 1, 'a': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10, 'k': 11, 'l': 12, 'm': 13, 'n': 14, 'o': 15, 'p': 16, 'q': 17, 'r': 18, 's': 19, 't': 20, 'u': 21, 'v': 22, 'w': 23, 'x': 24, 'z': 25, 'y': 26}
D - Strange Lunchbox
多次元DP
1:状態について
- 状態(i,j,k)はそれぞれ、何を表すのか?
- i:i個目のお弁当までチェックしましたよ
- 言い換えると、次チェックするのはi+1個目のお弁当について考えますよ
- 決して「i個のお弁当を購入しましたよ」ではない点に注意
- dpは、「1,4,5,7個目のお弁当を購入しました」という過程は残らない
- 多分ここ(途中経過)を無視して最小数を考えるから、bit全探索よりも早いんだと思う
- j : j個のたこ焼きを食べましたよ
- i個目のお弁当箱を確認(買う/買わないの選択)をして、j個のたこ焼きを食べた、の意
- k : k個のたこ焼きを食べましたよ
- i個目のお弁当箱を確認(買う/買わないの選択)をして、k個のたい焼きを食べた、の意
2:上限について
- なんで青木君に上げるのさ?????
- 高橋君はたこ焼きをX個を超えて食べる時、X+10個食べてもX+10000個食べても満足度は変わらないんですよね。
- つまり、いくつかのお弁当を買って、合計でX個以上のたこ焼きが入っていた場合、X食べたものとしてそれ以上は青木君にあげようね、という話
- だって、X個以上食べたとしても何個食べたなんて知らないよ、記録する必要がないもの
- 必要なのは高橋君が「X個食べました、満足しました」かどうか、っていう話だからね
- この「上限について」が、解説内dp[i][min(j+Ai,X)][Y]のmin(j+Ai,X)になる。
- Xを最大値とする。X以上はXとみなす
- たい焼きについても同上
3:dpの中身について
- 結局dp配列内部には何が収められているの?
- 状態(i,j,k)を添え字とした時、(dp[i][j][k])その状態になるために必要なお弁当の最小個数が入ってる
- 既にその状態に遷移したことがあるなら、「過去その状態に遷移した時のお弁当の最小個数」と「今回その状態に遷移する時に購入したお弁当の個数」を比較して、より小さい方(最短経路)を格納する
- これが添え字外、右辺のminの意味となりますね