2-B-1, 2-B-2

This commit is contained in:
xkm
2026-05-11 20:23:54 +08:00
parent 7ccb2ea522
commit 459af53f27
6 changed files with 236 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
module algo
go 1.26.3
+52
View File
@@ -0,0 +1,52 @@
package algo
func DP(arr []int) int {
n := len(arr) - 1
if n <= 0 {
return 0
}
const inf = int(^uint(0) >> 1)
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, n)
}
for length := 2; length <= n; length++ {
for l := 0; l+length-1 < n; l++ {
r := l + length - 1
dp[l][r] = inf
for k := l; k < r; k++ {
cost := dp[l][k] + dp[k+1][r] + arr[l]*arr[k+1]*arr[r+1]
if cost < dp[l][r] {
dp[l][r] = cost
}
}
}
}
return dp[0][n-1]
}
func Greedy(arr []int) int {
if len(arr) <= 2 {
return 0
}
dims := append([]int(nil), arr...)
cost := 0
for len(dims) > 2 {
best := 1
for i := 2; i < len(dims)-1; i++ {
if dims[i] > dims[best] {
best = i
}
}
cost += dims[best-1] * dims[best] * dims[best+1]
dims = append(dims[:best], dims[best+1:]...)
}
return cost
}
+61
View File
@@ -0,0 +1,61 @@
package algo
import (
"math/rand"
"testing"
)
func TestDPKnownCase(t *testing.T) {
arr := []int{30, 35, 15, 5, 10, 20, 25}
want := 15125
if got := DP(arr); got != want {
t.Fatalf("DP(%v) = %d, want %d", arr, got, want)
}
}
func TestGreedyRandomCompare(t *testing.T) {
r := rand.New(rand.NewSource(1))
for tc := 0; tc < 500; tc++ {
matrixCount := r.Intn(5) + 3
arr := make([]int, matrixCount+1)
for i := range arr {
arr[i] = r.Intn(9) + 2
}
greedy := Greedy(arr)
dp := DP(arr)
if greedy < dp {
t.Fatalf("greedy beat dp unexpectedly: arr=%v greedy=%d dp=%d", arr, greedy, dp)
}
}
}
func TestGreedyIsNotAlwaysOptimal(t *testing.T) {
r := rand.New(rand.NewSource(2))
found := false
for tc := 0; tc < 500; tc++ {
matrixCount := r.Intn(5) + 3
arr := make([]int, matrixCount+1)
for i := range arr {
arr[i] = r.Intn(9) + 2
}
greedy := Greedy(arr)
dp := DP(arr)
if dp < greedy {
t.Logf("found counterexample: arr=%v greedy=%d dp=%d", arr, greedy, dp)
found = true
}
if dp > greedy {
t.Fatalf("why greedy < dp???")
}
}
if !found {
t.Fatal("expected to find at least one case where dp < greedy")
}
}