Skip to content

Commit 701252d

Browse files
authored
Merge pull request #72 from myoshi2891/dev/macbook_pro
Dev/macbook pro
2 parents c5d9f64 + a4bec55 commit 701252d

9 files changed

Lines changed: 945 additions & 0 deletions

File tree

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// 以下は、**Go 1.20.6** を用いた「カエルの最小ジャンプコスト」問題の解法です。
2+
// **実行時間とメモリの消費量を最小限に抑える**ため、\*\*動的計画法(DP)+ 空間最適化(O(1) メモリ)\*\*を使用します。
3+
4+
// ## ✅ Go 実装(型明示・最小メモリ・高速)
5+
6+
package main
7+
8+
import (
9+
"bufio"
10+
"fmt"
11+
"os"
12+
"strconv"
13+
"strings"
14+
)
15+
16+
func min(a, b int) int {
17+
if a < b {
18+
return a
19+
}
20+
return b
21+
}
22+
23+
func main() {
24+
reader := bufio.NewReader(os.Stdin)
25+
26+
// 1行目:N
27+
line1, _ := reader.ReadString('\n')
28+
N, _ := strconv.Atoi(strings.TrimSpace(line1))
29+
30+
// 2行目:h[0]~h[N-1]
31+
line2, _ := reader.ReadString('\n')
32+
hStr := strings.Fields(line2)
33+
h := make([]int, N)
34+
for i := 0; i < N; i++ {
35+
h[i], _ = strconv.Atoi(hStr[i])
36+
}
37+
38+
if N == 2 {
39+
fmt.Println(abs(h[1] - h[0]))
40+
return
41+
}
42+
43+
var prev2 int = 0 // dp[i-2]
44+
var prev1 int = abs(h[1] - h[0]) // dp[i-1]
45+
46+
for i := 2; i < N; i++ {
47+
cost1 := prev1 + abs(h[i]-h[i-1])
48+
cost2 := prev2 + abs(h[i]-h[i-2])
49+
curr := min(cost1, cost2)
50+
prev2 = prev1
51+
prev1 = curr
52+
}
53+
54+
fmt.Println(prev1)
55+
}
56+
57+
func abs(a int) int {
58+
if a < 0 {
59+
return -a
60+
}
61+
return a
62+
}
63+
64+
// ## ✅ 入出力例
65+
66+
// 入力(標準入力):
67+
68+
// ```
69+
// 6
70+
// 30 10 60 10 60 50
71+
// ```
72+
73+
// 出力:
74+
75+
// ```
76+
// 40
77+
// ```
78+
79+
// ---
80+
81+
// ## ✅ 計算量・メモリ量
82+
83+
// | 指標 | 値 |
84+
// | ----- | --------------- |
85+
// | 時間計算量 | `O(N)` |
86+
// | 空間計算量 | `O(1)`(定数メモリのみ) |
87+
// | 入力制約 | `2 ≤ N ≤ 10^5` |
88+
89+
// ---
90+
91+
// ## ✅ ポイントまとめ
92+
93+
// * **配列 `dp[]` を使わず**に、`prev1`, `prev2` の2つだけで更新する。
94+
// * `abs()` でジャンプコストを計算。
95+
// * `min()` 関数で2通りのジャンプを比較。
96+
97+
// ---
98+
99+
// ## ✅ フルDP版(O(N)メモリ)も参考に:
100+
101+
// ```go
102+
// dp := make([]int, N)
103+
// dp[0] = 0
104+
// dp[1] = abs(h[1] - h[0])
105+
// for i := 2; i < N; i++ {
106+
// dp[i] = min(
107+
// dp[i-1]+abs(h[i]-h[i-1]),
108+
// dp[i-2]+abs(h[i]-h[i-2]),
109+
// )
110+
// }
111+
// fmt.Println(dp[N-1])
112+
// ```
113+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// 以下に、指定された条件(Node.js 18.16.1、`fs` モジュール使用、実行時間・メモリ効率重視)に従って、**カエルの最小コストジャンプ問題**をJavaScriptで解いた実装を示します。
2+
3+
// ---
4+
5+
// ## ✅ アルゴリズム概要(動的計画法DP)
6+
7+
// * `dp[i]`: 足場 `i` に到達するための最小コスト。
8+
// * 遷移式:
9+
10+
// * `dp[i] = min(dp[i-1] + abs(h[i] - h[i-1]), dp[i-2] + abs(h[i] - h[i-2]))`
11+
// * 初期値:
12+
13+
// * `dp[0] = 0`
14+
// * `dp[1] = abs(h[1] - h[0])`
15+
16+
// ---
17+
18+
// ## ✅ JavaScript (Node.js) 実装(`fs` 使用)
19+
20+
// ```javascript
21+
// const fs = require('fs');
22+
23+
// function main(input) {
24+
// const lines = input.trim().split('\n');
25+
// const N = parseInt(lines[0], 10);
26+
// const h = lines[1].split(' ').map(Number);
27+
28+
// const dp = new Array(N).fill(0);
29+
// dp[0] = 0;
30+
// dp[1] = Math.abs(h[1] - h[0]);
31+
32+
// for (let i = 2; i < N; i++) {
33+
// dp[i] = Math.min(
34+
// dp[i - 1] + Math.abs(h[i] - h[i - 1]),
35+
// dp[i - 2] + Math.abs(h[i] - h[i - 2])
36+
// );
37+
// }
38+
39+
// console.log(dp[N - 1]);
40+
// }
41+
42+
// // 標準入力から読み込む
43+
// main(fs.readFileSync('/dev/stdin', 'utf8'));
44+
// ```
45+
46+
// ---
47+
48+
// ## ✅ 計算量・メモリ使用量
49+
50+
// * **時間計算量**: `O(N)`(1回ずつループ)
51+
// * **空間計算量**: `O(N)`(DP配列1本)
52+
53+
// * さらに最適化すれば `O(1)` でも可能(直近2要素のみ使用)
54+
55+
// ---
56+
57+
// ## ✅ 最適化バージョン(メモリ `O(1)`)
58+
59+
// ```javascript
60+
const fs = require('fs');
61+
62+
function main(input) {
63+
const lines = input.trim().split('\n');
64+
const N = parseInt(lines[0], 10);
65+
const h = lines[1].split(' ').map(Number);
66+
67+
let prev2 = 0; // dp[i-2]
68+
let prev1 = Math.abs(h[1] - h[0]); // dp[i-1]
69+
70+
for (let i = 2; i < N; i++) {
71+
const curr = Math.min(
72+
prev1 + Math.abs(h[i] - h[i - 1]),
73+
prev2 + Math.abs(h[i] - h[i - 2])
74+
);
75+
prev2 = prev1;
76+
prev1 = curr;
77+
}
78+
79+
console.log(prev1);
80+
}
81+
82+
main(fs.readFileSync('/dev/stdin', 'utf8'));
83+
84+
// ## ✅ 入出力例テスト(例1)
85+
86+
// ```
87+
// 入力:
88+
// 4
89+
// 10 30 40 20
90+
91+
// 出力:
92+
// 30
93+
// ```
94+
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<!-- 以下は、**PHP 8.2.8** での「カエルの最小ジャンプコスト」問題の実装です。
2+
**処理時間・メモリの消費量を最小限に抑える**ため、\*\*動的計画法(DP)+ 空間最適化(O(1)メモリ)\*\*を採用しています。
3+
4+
---
5+
6+
## ✅ PHP 実装(型明示、O(1)メモリ最適化)
7+
<?php
8+
9+
function main(): void {
10+
$input = trim(stream_get_contents(STDIN));
11+
$lines = explode("\n", $input);
12+
13+
/** @var int $N */
14+
$N = (int)$lines[0];
15+
16+
/** @var array<int> $h */
17+
$h = array_map('intval', explode(' ', trim($lines[1])));
18+
19+
if ($N === 2) {
20+
echo abs($h[1] - $h[0]) . PHP_EOL;
21+
return;
22+
}
23+
24+
/** @var int $prev2 最小コスト(i-2) */
25+
$prev2 = 0;
26+
27+
/** @var int $prev1 最小コスト(i-1) */
28+
$prev1 = abs($h[1] - $h[0]);
29+
30+
for ($i = 2; $i < $N; ++$i) {
31+
/** @var int $cost1 足場 i-1 から来た場合のコスト */
32+
$cost1 = $prev1 + abs($h[$i] - $h[$i - 1]);
33+
34+
/** @var int $cost2 足場 i-2 から来た場合のコスト */
35+
$cost2 = $prev2 + abs($h[$i] - $h[$i - 2]);
36+
37+
/** @var int $curr 現在の足場 i への最小コスト */
38+
$curr = min($cost1, $cost2);
39+
40+
$prev2 = $prev1;
41+
$prev1 = $curr;
42+
}
43+
44+
echo $prev1 . PHP_EOL;
45+
}
46+
47+
main();
48+
49+
// ## ✅ 入出力形式
50+
51+
// 標準入力から以下の形式で与えられます:
52+
53+
// ```
54+
// N
55+
// h1 h2 h3 ... hN
56+
// ```
57+
58+
// ### 例:
59+
60+
// ```
61+
// 6
62+
// 30 10 60 10 60 50
63+
// ```
64+
65+
// 出力:
66+
67+
// ```
68+
// 40
69+
// ```
70+
71+
// ---
72+
73+
// ## ✅ 計算量とメモリ効率
74+
75+
// | 指標 | 値 |
76+
// | ----- | -------------- |
77+
// | 時間計算量 | O(N) |
78+
// | 空間計算量 | O(1)(定数個の変数のみ) |
79+
// | 入力制約 | 2 ≤ N ≤ 10⁵ |
80+
81+
// ## ✅ 解法のポイント
82+
83+
// * `dp[i]` の代わりに、**直前2ステップ(`prev1`, `prev2`)だけ保持**。
84+
// * `abs()` でジャンプコストを計算。
85+
// * \*\*配列未使用(O(N))\*\*のバージョンも実装可能。
86+
87+
// ## ✅ O(N) メモリバージョン(DP配列使用)
88+
89+
// 参考用に、メモリを多く使うフルDP版も示します:
90+
91+
// ```php
92+
// $dp = array_fill(0, $N, 0);
93+
// $dp[1] = abs($h[1] - $h[0]);
94+
// for ($i = 2; $i < $N; $i++) {
95+
// $dp[$i] = min(
96+
// $dp[$i - 1] + abs($h[$i] - $h[$i - 1]),
97+
// $dp[$i - 2] + abs($h[$i] - $h[$i - 2])
98+
// );
99+
// }
100+
// echo $dp[$N - 1] . PHP_EOL;
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# 以下は、**Python (CPython 3.11.4)** を用いた「カエルの最小ジャンプコスト」問題の解法です。
2+
# **処理時間・メモリ使用量を最適化**するため、**動的計画法(DP)+ メモリ O(1) に削減**した実装を提供します。
3+
4+
# ---
5+
6+
# ## ✅ Python 実装(型付き・高速・省メモリ)
7+
8+
# ```python
9+
import sys
10+
11+
def main() -> None:
12+
input: str = sys.stdin.read()
13+
lines: list[str] = input.strip().split('\n')
14+
15+
N: int = int(lines[0])
16+
h: list[int] = list(map(int, lines[1].split()))
17+
18+
if N == 2:
19+
print(abs(h[1] - h[0]))
20+
return
21+
22+
prev2: int = 0 # dp[0]
23+
prev1: int = abs(h[1] - h[0]) # dp[1]
24+
25+
for i in range(2, N):
26+
cost1: int = prev1 + abs(h[i] - h[i - 1])
27+
cost2: int = prev2 + abs(h[i] - h[i - 2])
28+
curr: int = min(cost1, cost2)
29+
prev2, prev1 = prev1, curr
30+
31+
print(prev1)
32+
33+
if __name__ == "__main__":
34+
main()
35+
36+
# ## ✅ 入出力形式
37+
38+
# 標準入力から以下のように与えられます:
39+
40+
# ```
41+
# N
42+
# h1 h2 h3 ... hN
43+
# ```
44+
45+
# ---
46+
47+
# ## ✅ 実行例
48+
49+
# 入力:
50+
51+
# ```
52+
# 6
53+
# 30 10 60 10 60 50
54+
# ```
55+
56+
# 出力:
57+
58+
# ```
59+
# 40
60+
# ```
61+
62+
# ---
63+
64+
# ## ✅ 計算量とメモリ使用量
65+
66+
# | 項目 | 内容 |
67+
# | ----- | ------------------------------ |
68+
# | 時間計算量 | `O(N)`(1ループ) |
69+
# | 空間計算量 | `O(1)`(直前2個のみ) |
70+
# | 入力制約 | `2 ≤ N ≤ 10^5`、`1 ≤ hᵢ ≤ 10^4` |
71+
72+
# ---
73+
74+
# ## ✅ 補足:DP配列を使ったフル版(メモリ O(N))
75+
76+
# 必要であれば以下のようにも書けます:
77+
78+
# ```python
79+
# dp: list[int] = [0] * N
80+
# dp[1] = abs(h[1] - h[0])
81+
# for i in range(2, N):
82+
# dp[i] = min(dp[i-1] + abs(h[i] - h[i-1]), dp[i-2] + abs(h[i] - h[i-2]))
83+
# print(dp[N-1])
84+
# ```

0 commit comments

Comments
 (0)