题目描述
假设书本的叠放有这样的规则,当A书的长度和宽度都大于B书时,可以将其B书置于A的上方,堆叠摆放,请设计一个程序,根据输入的书本长宽,计算最多可以堆叠摆放多少本书?
输入
[[16,15], [13, 12], [15, 14]]
输出
3
说明
这里代表有3本书,第1本长宽分别为16和15,第2本长宽为13和12,第3本长宽为15和14,它们可以按照[13, 12],[15, 14],[16,15]
的顺序堆叠,所以输出3
动态规划,实质是求 最长递增子序列,但本题有两个因素需要考虑,可以通过排序将长度置为有序,这样其实就是对宽度求最长递增子序列,且可能存在长度相同的情况,在更新dp数组判定时,也要考虑到
package main import ( "fmt" "regexp" "sort" "strconv" ) type Book struct { Height int Width int } type books []Book func (b books) Len() int { return len(b) } func (b books) Swap(i,j int){ b[i],b[j] = b[j],b[i] } func (b books) Less(i,j int) bool{ if b[i].Height == b[j].Height{ return b[i].Width < b[j].Width } return b[i].Height < b[j].Height } func main() { input := "[[7, 11], [10, 9], [10, 11], [13, 12], [15, 14], [16,15]]" re := regexp.MustCompile("[0-9]+") numbers := re.FindAllString(input, -1) theBook := make(books,len(numbers)/2) for i:=0;i<len(numbers)/2;i++{ theBook[i].Height,_= strconv.Atoi(numbers[2*i]) theBook[i].Width,_= strconv.Atoi(numbers[2*i+1]) } sort.Sort(theBook) res := 1 dp := make([]int,len(theBook)) for k:= range dp{ dp[k]=1 } //动态规划 for i:=1;i<len(theBook);i++{ cur := theBook[i] for j:=0;j<i;j++{ pre := theBook[j] if cur.Height > pre.Height && cur.Width > pre.Width{ dp[i] = max(dp[i],dp[j]+1) } res = max(res,dp[i]) } } fmt.Println(res) } func max (x,y int) int{ if x > y{ return x }else { return y } }