diff --git a/1937.Maximum-Number-of-Points-with-Cost/memo.md b/1937.Maximum-Number-of-Points-with-Cost/memo.md new file mode 100644 index 0000000..0b4634a --- /dev/null +++ b/1937.Maximum-Number-of-Points-with-Cost/memo.md @@ -0,0 +1,35 @@ +# 1937. Maximum Number of Points with Cost + +## step1 + +dp を使えそうだと思った。計算量 O(mn^2) の解法しか思いつかず、TLE した解法: step1_TLE.py + +28mほど経過して諦めて答えを見る + +# step2 + +https://leetcode.com/problems/maximum-number-of-points-with-cost/solutions/1344888/c-dp-from-om-n-n-to-om-n-by-npes87184-waex/?envType=problem-list-v2&envId=7p55wqm + +各行の更新にもDPをつかう。これで正しいのか分からなかったので考えてみる + + left[c] += max_{i<=c}(dp_prev[i] - (c-i)) += max_{i<=c}(dp_prev[i] + i) - c += max(max_{i<=c-1}(dp_prev[i] + i), dp_prev[c] + c) - c += max(max_{i<=c-1}(dp_prev[i] + i) - (c - 1) - 1, dp_prev[c]) += max(left[c-1] - 1, dp_prev[c]) + +1マスずれるたびに一律に1ペナルティが発生するから前の列の値を使える + +rightも同様 + +--- + +running_max という変数を使って配列の生成コストをなくす + +これ以外の解法は思いつかない + +## step3 +TODO + + diff --git a/1937.Maximum-Number-of-Points-with-Cost/step1_TLE.py b/1937.Maximum-Number-of-Points-with-Cost/step1_TLE.py new file mode 100644 index 0000000..f507203 --- /dev/null +++ b/1937.Maximum-Number-of-Points-with-Cost/step1_TLE.py @@ -0,0 +1,19 @@ +class Solution: + def maxPoints(self, points: List[List[int]]) -> int: + if not points or not points[0]: + return 0 + + num_rows = len(points) + num_cols = len(points[0]) + + dp_prev = points[0][:] + dp = [0] * num_cols + + for r in range(1, num_rows): + for c in range(num_cols): + dp[c] = max([dp_prev[c_prev] - abs(c - c_prev) for c_prev in range(num_cols)]) + points[r][c] + dp, dp_prev = dp_prev, dp + + return max(dp_prev) + + diff --git a/1937.Maximum-Number-of-Points-with-Cost/step2.py b/1937.Maximum-Number-of-Points-with-Cost/step2.py new file mode 100644 index 0000000..d9da28b --- /dev/null +++ b/1937.Maximum-Number-of-Points-with-Cost/step2.py @@ -0,0 +1,28 @@ +class Solution: + def maxPoints(self, points: List[List[int]]) -> int: + if not points or not points[0]: + return 0 + + num_rows = len(points) + num_cols = len(points[0]) + + dp_prev = points[0][:] + dp = [0] * num_cols + + for r in range(1, num_rows): + left = [0] * num_cols + left[0] = dp_prev[0] + for c in range(1, num_cols): + left[c] = max(left[c - 1] - 1, dp_prev[c]) + + right = [0] * num_cols + right[-1] = dp_prev[-1] + for c in range(num_cols - 2, -1, -1): + right[c] = max(right[c + 1] - 1, dp_prev[c]) + + for c in range(num_cols): + dp[c] = points[r][c] + max(left[c], right[c]) + + dp_prev, dp = dp, dp_prev + + return max(dp_prev) diff --git a/1937.Maximum-Number-of-Points-with-Cost/step2_running_max.py b/1937.Maximum-Number-of-Points-with-Cost/step2_running_max.py new file mode 100644 index 0000000..348295a --- /dev/null +++ b/1937.Maximum-Number-of-Points-with-Cost/step2_running_max.py @@ -0,0 +1,25 @@ +class Solution: + def maxPoints(self, points: List[List[int]]) -> int: + if not points or not points[0]: + return 0 + + num_rows = len(points) + num_cols = len(points[0]) + + dp_prev = points[0][:] + dp = [0] * num_cols + + for r in range(1, num_rows): + running_max = 0 + for c in range(num_cols): + running_max = max(running_max - 1, dp_prev[c]) + dp[c] = running_max + + running_max = 0 + for c in range(num_cols - 1, -1, -1): + running_max = max(running_max - 1, dp_prev[c]) + dp[c] = max(dp[c], running_max) + points[r][c] + + dp_prev, dp = dp, dp_prev + + return max(dp_prev)