add 41_dp
This commit is contained in:
parent
fdf388e069
commit
22028106dd
102
go/41_dynamic_programming/backtracking/leastcoins.go
Normal file
102
go/41_dynamic_programming/backtracking/leastcoins.go
Normal file
@ -0,0 +1,102 @@
|
||||
package dp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const intMax = int(^uint(0) >> 1)
|
||||
|
||||
var Cnt int
|
||||
|
||||
// LeastCoins find least number of coins of which the total values are equals a given one
|
||||
func LeastCoins(targetTotal int, coinOptions []int) int {
|
||||
minNum := intMax
|
||||
|
||||
memo := make([][]int, targetTotal+1)
|
||||
for i := range memo {
|
||||
memo[i] = make([]int, len(coinOptions))
|
||||
}
|
||||
fmt.Println("start")
|
||||
leastCoins(&minNum, 0, targetTotal, len(coinOptions)-1, coinOptions, memo)
|
||||
fmt.Println("end")
|
||||
|
||||
return minNum
|
||||
|
||||
}
|
||||
|
||||
func leastCoins(minNum *int, cNum, totalValue, opIndex int, coinOptions []int, memo [][]int) {
|
||||
Cnt++
|
||||
if 0 == totalValue {
|
||||
if cNum < *minNum {
|
||||
*minNum = cNum
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if opIndex < 0 {
|
||||
return
|
||||
}
|
||||
|
||||
num4Option := 0
|
||||
remaining := totalValue - coinOptions[opIndex]*num4Option
|
||||
for remaining >= 0 {
|
||||
|
||||
if opIndex != 0 {
|
||||
if shouldSkip(memo, remaining, opIndex-1, cNum+num4Option) {
|
||||
goto Next
|
||||
}
|
||||
}
|
||||
leastCoins(minNum, cNum+num4Option, remaining, opIndex-1, coinOptions, memo)
|
||||
|
||||
Next:
|
||||
num4Option++
|
||||
remaining = totalValue - coinOptions[opIndex]*num4Option
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func shouldSkip(memo [][]int, totalValue, nextOpIdex, cNum int) bool {
|
||||
if memo[totalValue][nextOpIdex] > 0 && memo[totalValue][nextOpIdex] <= cNum {
|
||||
fmt.Printf("skip,%d, %d as %d <= %d \n", totalValue, nextOpIdex, memo[totalValue][nextOpIdex], cNum)
|
||||
return true
|
||||
}
|
||||
if memo[totalValue][nextOpIdex] == 0 || memo[totalValue][nextOpIdex] > cNum {
|
||||
memo[totalValue][nextOpIdex] = cNum
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func LeastCoins2(targetTotal int, coinOptions []int) int {
|
||||
|
||||
minNum := intMax
|
||||
memo := make([][]bool, targetTotal)
|
||||
for i := range memo {
|
||||
memo[i] = make([]bool, targetTotal/coinOptions[0])
|
||||
}
|
||||
|
||||
fmt.Println("start")
|
||||
leastCoins2(&minNum, targetTotal, coinOptions, 0, 0, memo)
|
||||
fmt.Println("end")
|
||||
|
||||
return minNum
|
||||
|
||||
}
|
||||
|
||||
func leastCoins2(minNum *int, targetTotal int, coinOptions []int, cNum, cValue int, memo [][]bool) {
|
||||
Cnt++
|
||||
if cValue == targetTotal {
|
||||
if *minNum > cNum {
|
||||
*minNum = cNum
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for _, coin := range coinOptions {
|
||||
if coin+cValue <= targetTotal && !memo[cValue+coin-1][cNum] {
|
||||
memo[cValue+coin-1][cNum] = true
|
||||
leastCoins2(minNum, targetTotal, coinOptions, cNum+1, cValue+coin, memo)
|
||||
}
|
||||
}
|
||||
}
|
56
go/41_dynamic_programming/backtracking/leastcoins_test.go
Normal file
56
go/41_dynamic_programming/backtracking/leastcoins_test.go
Normal file
@ -0,0 +1,56 @@
|
||||
package dp
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestFindLeastCoins(t *testing.T) {
|
||||
|
||||
coinOptions := []int{1, 3, 5, 10, 50}
|
||||
|
||||
Cnt = 0
|
||||
result := LeastCoins(9, coinOptions)
|
||||
|
||||
t.Log("test 1 =====================")
|
||||
if result != 3 {
|
||||
t.Logf("least coins %d", result)
|
||||
t.Error("failed")
|
||||
}
|
||||
t.Logf("cnt===%d", Cnt)
|
||||
|
||||
Cnt = 0
|
||||
t.Log("test 2 =====================")
|
||||
result = LeastCoins(36, coinOptions)
|
||||
|
||||
if result != 5 {
|
||||
t.Logf("least coins %d", result)
|
||||
t.Error("failed")
|
||||
}
|
||||
t.Logf("cnt===%d", Cnt)
|
||||
|
||||
}
|
||||
|
||||
func TestFindLeastCoins2(t *testing.T) {
|
||||
|
||||
coinOptions := []int{1, 3, 5, 10, 50}
|
||||
|
||||
Cnt = 0
|
||||
result := LeastCoins2(9, coinOptions)
|
||||
|
||||
t.Log("test 1 =====================")
|
||||
if result != 3 {
|
||||
t.Logf("least coins %d", result)
|
||||
t.Error("failed")
|
||||
}
|
||||
|
||||
t.Logf("cnt===%d", Cnt)
|
||||
|
||||
Cnt = 0
|
||||
t.Log("test 2 =====================")
|
||||
result = LeastCoins2(36, coinOptions)
|
||||
|
||||
if result != 5 {
|
||||
t.Logf("least coins %d", result)
|
||||
t.Error("failed")
|
||||
}
|
||||
t.Logf("cnt===%d", Cnt)
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user