http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2266
箱が1つなら簡単。
箱がmつの時はM-1個の箱がコストを節約するために使えると考えられる。
どれくらいコストを節約できるか考えよう。
あるボールを時刻sに入れ、次に入れる時刻をtとしよう。
すると時刻[s+1,t)においてボールを入れ続けることが出来ればボールのコストを削減できる。
なのでこのような区間の重なりがM-1以上にならないようにコストを最大化する問題になる。
これは蟻本のPOJ 3680と同じ問題なので解けた。
問題の咀嚼が難しい。こういう言い換えは思いつかない。
ボールだけに注目したり、箱のみに注目したり…みたいに「部分」に注目すると気付きやすい?
解説を読んでいると
http://blog.hatena.ne.jp/omochangram/omochan.hatenablog.com/edit?entry=8599973812276127257
と少し似ているなと思った。
使っているんだけど使っていないことにしたり、使うものをストックしといて後に使ったり。時系列でものを使っていくときのテクニック?
int M, N, K; int A[MAX_N]; vector<int> B[MAX_N]; void solve() { cin >> M >> N >> K; int res = 0; MCF::init(K); rep(i, 0, N) cin >> A[i]; rep(i, 0, K) { int a; cin >> a; a--; B[a].push_back(i); res += A[a]; } rep(i, 0, N) { if((int)B[i].size() <= 1) continue; rep(j, 0, (int)B[i].size() - 1) { int n1 = B[i][j], n2 = B[i][j + 1]; if(n1 + 1 != n2) MCF::add_edge(n1 + 1, n2, 1, -A[i]); else res -= A[i]; } } rep(i, 0, K - 1) MCF::add_edge(i, i + 1, M, 0); cout << res + MCF::get(0, K - 1, M - 1) << "\n"; }
How to Create a Good Gameは何とかして倒したい。