/*
难度:中等
有一堆石头,每块石头的重量都是正整数,
每一回合,从中选出任意两块石头: 如果重量不等,则将较轻的石头粉碎,然后将两者重量之差赋给较重的那块石头;如果重量相等,则两块都粉碎,
最后,最多只会剩下一块石头,求此石头最小的可能重量。如果没有石头剩下,则返回0。
示例:
输入:[2,7,4,1,8,1]
输出:1
解释:
组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1],
组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1],
组合 2 和 1,得到 1,所以数组转化为 [1,1,1],
组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。
*/
extension Daily {
static func test_leetcode1049() {
let nums = [2,7,4,1,8,1]
if let res = Daily.leetcode1049(stones: nums) {
print("最终结果 \(res)")
}
}
static func leetcode1049(stones: [Int]) -> Int? {
if stones.count < 1 {
// print("nums is empty")
return 0
}
if stones.count == 1 {
return stones[0]
}
if stones.count == 2 {
return abs(stones[0] - stones[1])
}
var sum = 0
for item in stones {
sum += item
}
// print("sum=\(sum)")
let rows = stones.count + 1
let cols = sum/2 + 1
var map = Array(repeating: 0, count: rows * cols)
for idx1 in 1..<rows {
let current = stones[idx1-1] //当前石头重量
for idx2 in 1..<cols {
let cidx = idx1 * cols + idx2
let cidxTop = cidx - cols
if current < idx2 {
map[cidx] = map[cidxTop] + map[(idx1-1)*cols + idx2 - current]
}
else if current == idx2 {
map[cidx] = map[cidxTop] + 1
}
else {
map[cidx] = map[cidxTop]
}
}
}
//找到第一个不为0的
var exist = 0
aloop: for idx1 in stride(from: cols-1, through: 0, by: -1) {
for idx2 in stride(from: rows-1, through: 0, by: -1) {
if map[idx2*cols + idx1] > 0 {
exist = idx1
break aloop
}
}
}
// print("最大: \(exist)")
//找出一种可能的解法
// floop: for idx1 in stride(from: cols-1, through: 0, by: -1) {
// for idx2 in 1..<rows {
// var cur = map[idx2*cols + idx1]
// var top = map[idx2*cols + idx1 - cols]
// var count = 0
// var nextcol = idx1
// var nextrow = idx2
// var choosed = [Int]()
// if cur <= top {
// continue
// }
// while nextrow > 0 && nextcol > 0 {
// cur = map[nextrow*cols + nextcol]
// top = map[nextrow*cols + nextcol - cols]
// if cur == 0 {
// count = 0
// break
// }
// if cur > top {
// choosed.append(stones[nextrow-1])
// count += 1
// nextcol = nextcol - stones[nextrow-1]
// nextrow -= 1
// }
// else {
// nextrow -= 1
// }
// }
// if count > 0 {
// print("一种解法:\(idx1), \(idx2), \(choosed)")
// }
// break floop
// }
// }
return sum - 2*exist
}
}
06-10
292
06-08
183
12-30
1451
07-13
342