https://beta.atcoder.jp/contests/abc104/tasks/abc104_c
前提知識
解法
https://beta.atcoder.jp/contests/abc104/submissions/2956491
点数は全て100の倍数なので、全て100分の1にして考えることにする。
Gの上限が書かれていないので、上限をまずは見積もろう。
取りうる最大得点は
問題で得られる得点:1*100+2*100+3*100+...+10*100=5500
ボーナスで得られる得点:10^4*10=10^5
なので10^5+5500が最大得点になる。よって、これがGの上限。
ここからDPを考える。
dp[i][point] := i番目の問題まででpoint点得るための最小問題数
遷移はi+1番目で何個取るかなので、最大100通り。
iは10通りでpointは10^5位なので、全体で10^8くらいになる。
DPは基本軽いのでこれくらいなら大丈夫。
あとは、pointがG以上で問題数が小さいものを取ると答え。
※書いてて気がついたが「dp[i][num] := i番目の問題まででnum問題解いたときの最大点数」でやったほうが良かったかも
int D, G, P[10], C[10]; int dp[11][401010]; //--------------------------------------------------------------------------------------------------- void _main() { cin >> D >> G; rep(i, 0, D) cin >> P[i] >> C[i]; G /= 100; rep(i, 0, D) C[i] /= 100; rep(i, 0, D + 1) rep(point, 0, 201010) dp[i][point] = inf; dp[0][0] = 0; rep(i, 0, D) rep(point, 0, 201010) { rep(j, 0, P[i]) chmin(dp[i + 1][point + (i + 1)*j], dp[i][point] + j); chmin(dp[i + 1][point + (i + 1)*P[i] + C[i]], dp[i][point] + P[i]); } int ans = inf; rep(point, G, 201010) chmin(ans, dp[D][point]); cout << ans << endl; }