package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
type SubsetSumProblem struct {
Nums []int
Target int
}
func NewSubsetSumProblem(nums []int, target int) *SubsetSumProblem {
sort.Ints(nums)
s := &SubsetSumProblem{Nums: nums, Target: target}
return s
}
func (s *SubsetSumProblem) Solve() []int {
work := make([]int, s.Target+1, s.Target+1)
work[0] = 0
for i := 1; i < len(work); i++ {
work[i] = -1
}
for _, n := range s.Nums {
for i := s.Target; i >= 0; i-- {
if work[i] == -1 {
continue
}
if i+n <= s.Target && work[i+n] == -1 {
work[i+n] = n
}
}
if work[s.Target] != -1 {
break
}
}
return s.ToResult(work)
}
func (s *SubsetSumProblem) ToResult(work []int) []int {
result := []int{}
if work[s.Target] != -1 {
for s.Target > 0 {
result = append(result, work[s.Target])
s.Target -= work[s.Target]
}
}
return result
}
// 試行回数
const sample = 10000
// 候補になるピーマンの個数
const length = 12
// 最小のピーマンの重さ
const lowest = 20
// 最大のピーマンの重さ
const highest = 60
// 合計の重さ
const target = 150
func main() {
rand.Seed(time.Now().Unix())
count := 0
for i := 0; i < sample; i++ {
p := make([]int, length, length)
for i := range p {
p[i] = rand.Intn(highest-lowest) + lowest
}
s := NewSubsetSumProblem(p, target)
result := s.Solve()
if len(result) == 0 {
count++
}
}
percent := 100.0 - (float32(count) / float32(sample) * 100.0)
fmt.Printf("%d 回成功 (%.1f%%)", sample - count, percent)
}