package main
import ( "fmt" "math" "math/rand" "sort" "time")
func minCost1(n, m int, arr [][]int) int { cnts := make([]int, n+1) for _, p := range arr { cnts[p[0]]++ } needChange := false for i := 2; i <= n; i++ { if cnts[i] >= cnts[1] { needChange = true break } } if !needChange { return 0 } return process(arr, 0, n, make([]bool, m))}
func process(arr [][]int, i, n int, change []bool) int { if i == len(arr) { cnts := make([]int, n+1) sum := 0 for j := 0; j < len(arr); j++ { if change[j] { cnts[1]++ sum += arr[j][1] } else { cnts[arr[j][0]]++ } } ok := true for j := 2; j <= n; j++ { if cnts[j] >= cnts[1] { ok = false break } } if !ok { return math.MaxInt64 } else { return sum } } else { p1 := math.MaxInt64 if arr[i][0] != 1 { change[i] = true p1 = process(arr, i+1, n, change) change[i] = false } p2 := process(arr, i+1, n, change) return min(p1, p2) }}
func minCost2(n, m int, arr [][]int) int { cnts := make([]int, n+1) for _, p := range arr { cnts[p[0]]++ } needChange := false for i := 2; i <= n; i++ { if cnts[i] >= cnts[1] { needChange = true break } } if !needChange { return 0 } sort.Slice(arr, func(i, j int) bool { return arr[i][1] < arr[j][1] }) shops := make([][]int, n+1) for i := 0; i <= n; i++ { shops[i] = []int{} } for i := 0; i < m; i++ { shops[arr[i][0]] = append(shops[arr[i][0]], i) } used := make([]bool, m) ans := math.MaxInt64 for i := cnts[1] + 1; i <= m; i++ { money := f(arr, n, cnts[1], i, shops, used) if money != -1 { ans = min(ans, money) } } return ans}
func f(arr [][]int, n, already, must int, shops [][]int, used []bool) int { for i := 0; i < len(used); i++ { used[i] = false } sum := int(0) for i := 2; i <= n; i++ { needChange := max(0, len(shops[i])-must+1) for j := 0; j < needChange; j++ { people := shops[i][j] sum += int(arr[people][1]) used[people] = true } already += needChange if already > must { return -1 } } for i, j := 0, 0; already+j < must; i++ { if arr[i][0] != 1 && !used[i] { sum += arr[i][1] j++ } } return sum}
func randomArray(len, n, v int) [][]int { arr := make([][]int, len) for i := 0; i < len; i++ { arr[i] = []int{ rand.Intn(n) + 1, rand.Intn(v) + 1, } } return arr}
func min(a, b int) int { if a < b { return a } return b}
func max(a, b int) int { if a > b { return a } return b}
func main() { rand.Seed(time.Now().Unix()) N := 10 M := 16 V := 100 testTimes := 10000
fmt.Println("测试开始") for i := 0; i < testTimes; i++ { n := rand.Intn(N) + 1 m := rand.Intn(M) + 1 arr := randomArray(m, n, V) ans1 := minCost1(n, m, arr) ans2 := minCost2(n, m, arr) if ans1 != ans2 { fmt.Println("出错了!") fmt.Println("n : ", n) fmt.Println("m : ", m) for _, p := range arr { fmt.Println(p[0], " , ", p[1]) } fmt.Println(ans1) fmt.Println(ans2) break } } fmt.Println("测试结束")
n := 3000 m := 3000 v := 1000000000 arr := randomArray(n, m, v) start := time.Now() minCost2(n, m, arr) end := time.Now() fmt.Println("最大数据量时的运行时间 : ", end.Sub(start).Milliseconds(), " 毫秒")}
评论