Skip to content

Commit

Permalink
Update 037.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Reputeless committed May 1, 2022
1 parent c8c8fb4 commit 226ac1e
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions 037.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ int main()

for (int i = 1; i <= N; ++i) // i 個目の料理を見る
{
// 現在の料理を作らなかった場合の状態(直前の料理と同じ)を設定
// 現在の料理を作らなかった場合の状態(直前の料理完了時点と同じ)を設定
dp[i] = dp[i - 1];

// 見ている料理
Expand Down Expand Up @@ -225,36 +225,49 @@ int main()

for (int i = 1; i <= N; ++i) // i 個目の料理を見る
{
// 現在の料理を作らなかった場合の状態(直前の料理完了時点と同じ)を設定
dp[i] = dp[i - 1];

// 見ている料理
const auto& dish = dishes[i - 1];

// k: 香辛料の合計量
for (int k = 0; k <= W; ++k)
{
// 現在の料理で [香辛料の合計量] k を実現するために必要な,
// 直前の料理における [香辛料の合計量] の最小値
const int fromBegin = std::max(0, (k - dish.R));

// 現在の料理で [香辛料の合計量] k を実現するために必要な,
// 直前の料理における [香辛料の合計量] の最大値(の次の要素を指して, 範囲の終端位置を表現)
const int fromEnd = std::max(0, (k - dish.L + 1));

// [fromBegin, fromEnd) で範囲を表す. (fromBegin == fromEnd) の場合は, 実現不可能
if (fromBegin == fromEnd)
{
continue;
}

// セグメント木による区間最大値取得.
// [fromBegin, fromEnd) の中で最大の価値合計値を探す
const long long max = rmqs[i - 1].prod(fromBegin, fromEnd);

// 最大の価値合計値 -1 は, 直前の状態が実現不可能ということなのでスキップ
if (max != -1)
{
// 料理を作らない場合と作る場合の価値合計値を比較して, 大きいほうを採用
dp[i][k] = std::max(dp[i][k], (max + dish.V));
}
}

// セグメント木を更新
for (int k = 0; k <= W; ++k)
{
rmqs[i].set(k, dp[i][k]);
}
}

// 解答を出力
// 解答 (dp[N][W]) を出力
std::cout << dp.back().back() << '\n';
}
```
Expand Down Expand Up @@ -301,25 +314,42 @@ int main()
for (int i = 1; i <= N; ++i) // i 個目の料理を見る
{
// 現在の料理を作らなかった場合の状態(直前の料理完了時点と同じ)を設定
dp[i] = dp[i - 1];
// 見ている料理
const auto& dish = dishes[i - 1];
// k: 香辛料の合計量
for (int k = 0; k <= W; ++k)
{
// 現在の料理で [香辛料の合計量] k を実現するために必要な,
// 直前の料理における [香辛料の合計量] の最小値へのイテレータ
const auto itBegin = (dp[i - 1].begin() + std::max(0, (k - dish.R)));
// 現在の料理で [香辛料の合計量] k を実現するために必要な,
// 直前の料理における [香辛料の合計量] の最大値(への次の要素を指して, 範囲の終端位置を表現)するイテレータ
const auto itEnd = (dp[i - 1].begin() + std::max(0, (k - dish.L + 1)));
// [itBegin, itEnd) で範囲を表す. (itBegin == itEnd) の場合は, 実現不可能
if (itBegin == itEnd)
{
continue;
}
// [itBegin, itEnd) の中で最大の価値合計値を探す
const auto it = std::max_element(itBegin, itEnd);
if (it != itEnd && *it != -1)
// 最大の価値合計値 -1 は, 直前の状態が実現不可能ということなのでスキップ
if (*it != -1)
{
// 料理を作らない場合と作る場合の価値合計値を比較して, 大きいほうを採用
dp[i][k] = std::max(dp[i][k], (*it + dish.V));
}
}
}
// 解答を出力
// 解答 (dp[N][W]) を出力
std::cout << dp.back().back() << '\n';
}
```

0 comments on commit 226ac1e

Please sign in to comment.