1011. capacity to ship packages within d days#44
Conversation
| ``` | ||
|
|
||
| --- | ||
| 高速化を考える,やりたいことは「適切な`capacity`の値を見つける」. |
| # Step 1 | ||
|
|
||
| 愚直に解いたものが[Code1](#Code1)で,TLE.方針は | ||
| - `weights`の最小値よりcapacityは大きくなくてはならないので,`capacity`をここからスタート |
|
|
||
| 愚直に解いたものが[Code1](#Code1)で,TLE.方針は | ||
| - `weights`の最小値よりcapacityは大きくなくてはならないので,`capacity`をここからスタート | ||
| - `capacity`に対して輸送にかかる日数を算出し,これが`days`より大きくなるまで`capacity`をインクリメントしていく. |
|
|
||
| --- | ||
| 高速化を考える,やりたいことは「適切な`capacity`の値を見つける」. | ||
| - 最小でも一つは荷物を運べなきゃいけないから,下限として`min(weights)` |
There was a problem hiding this comment.
書いていてごっちゃになっていました.
何度もご指摘ありがとうございます🙇
| int min_capacity = *std::max_element(weights.begin(), weights.end()); | ||
| int max_capacity = std::reduce(weights.begin(), weights.end()); |
There was a problem hiding this comment.
もうちょっとbinary searchっぽい変数名をつけた方がわかりやすいかもしれません。
| if (necessary_days > days) { | ||
| min_capacity = capacity + 1; | ||
| } else { | ||
| max_capacity = capacity - 1; |
There was a problem hiding this comment.
max_capacity = capacity;にして、while (min_capacity < max_capacity)とする方が自然に思いました。
| // capacity < min_capacityなるcapacityに対し,necessary_days > daysである | ||
| // max_capacity < capacityなるcapacityに対し,necessary_days <= daysである |
There was a problem hiding this comment.
これは言わんとすることはわかるのですが、max_capacity <= capacityなるcapacityに対し,necessary_days <= daysであるとする方が自然でわかりやすいと思います。最後にmin_capacity - 1 == max_capacityの形になっていることがわからないと読み取れないですよね。
There was a problem hiding this comment.
上のコメントと合わせて,探索区間を半開区間で捉えるということですね.
確かにこちらの方がmin_capacityがちょうど欲しい位置を指していることを読み取りやすいです.
| } | ||
| if (loading_weight + weight > capacity) { | ||
| loading_weight = 0; | ||
| ++necessary_days; |
| という点で違いがある.なおLeetCodeではC++23のため並列化はできなかった. | ||
|
|
||
| --- | ||
| pythonみたいに`range()`が使えれば`lower_bound`をそのまま使えるのになー,と思っていたら[`std::iota`](https://cpprefjp.github.io/reference/numeric/iota.html)とかいう便利なものを見つけた.これと`lower_bound`を使って書いたのが[Code5](#Code5). |
There was a problem hiding this comment.
std::views::iotaを使えば良さそうです。
https://en.cppreference.com/w/cpp/ranges/iota_view.html
There was a problem hiding this comment.
ありがとうございます!viewにもiotaがあったのですね,見落としていました.
|
|
||
| std::vector<int> capacities(max_capacity - min_capacity + 1); | ||
| std::iota(capacities.begin(), capacities.end(), min_capacity); | ||
| std::transform( |
There was a problem hiding this comment.
iotaは上でコメントありましたが、全ての値をboolに変換してしまったら、二分探索する意味がないですね。
There was a problem hiding this comment.
結局ここで線形時間かかるから,ということですね.
transformを使うならば,並列化するなどして十分に定数倍の高速化を行う必要がありました.
| } | ||
|
|
||
| private: | ||
| int CanBeShipped(const vector<int>& weights, int capacity, int days) { |
1011. Capacity To Ship Packages Within D Days