時間目にモチベーションが 、現実逃避度が になるように行動したときの達成しうる勉強量の最大値
とします。また、そのような状況になるような行動が存在しない場合は とします。
いま求めたい量は
です。
便宜上勉強をリフレッシュ とし、 とします。
そして、勉強量増加量
を定めます。
明らかに、 となる場合はそこからすべて勉強する方がいいので を仮定します。
そうすると、このdpは初期値を
として、遷移は以下のように書くことができます。
とする。(それぞれ、下限 、下限 上限 に丸める関数)
各 について、 として
以上を適切に実装することで、モチベーションの最大値を として、 でこの問題を解くことができました。
実装例(C++)
#include <bits/stdc++.h>
using namespace std;
void chmax(int& l, int r) { l = max(l, r); }
int main()
{
int N, P, H, DM, DA;
cin >> N >> P >> H;
cin >> DM >> DA;
vector<pair<int, int>> refresh(N + 1);
refresh[0] = {-DM, -DA};
for (int i = 1; i <= N; i++)
cin >> refresh[i].first >> refresh[i].second;
vector<vector<int>> dp(101, vector<int>(P + 1, -1e9));
dp[0][0] = 0;
for (int h = 0; h < H; h++)
{
vector<vector<int>> nxt = dp;
for (int m = 0; m <= 100; m++)
for (int a = 0; a <= P; a++)
for (int i = 0; i <= N; i++)
if (a + refresh[i].second <= P)
{
int nm = min(100, max(0, m + refresh[i].first));
int na = max(0, a + refresh[i].second);
chmax(nxt[nm][na], dp[m][a] + (i == 0 ? nm : 0));
}
swap(dp, nxt);
}
int ans = 0;
for (int m = 0; m <= 100; m++)
for (int a = 0; a <= P; a++)
chmax(ans, dp[m][a]);
cout << ans << endl;
}
ユーザー解説
ユーザー解説を書くユーザー解説はまだありません。