动态规划就是把一个大问题分解为多个小问题,然后一个个去解决。
Fibonacci:
直接输出最后的结果,不保存中间的数据。
func Fibonacci(n int) int {
if n <= 1 {
return n
}
i, j := 0, 1
for p := 2; p <= n; p++ {
tmp := i + j
i = j
j = tmp
}
return j
}
func main() {
//fun(0)
i := Fibonacci(4)
fmt.Println(i)
}
变态青蛙跳台阶问题:青蛙一次可以跳一级台阶,也可以跳2级,也可以跳n级,问n级台阶,青蛙有多少种跳法。
列出前四级台阶的方案数,可以发现两种规律,一是从第二级开始,每一级的方案数是上一级的方案数的2倍,二是每一级的方案数是2的级数减一的次方。
func JumpFloor(n int) int {
if n == 1 {
return n
}
tmp := 1
for i := 2; i <= n; i++ {
tmp *= 2
}
return tmp
}
func JumpFloor1(n int) int {
return 1 << (n - 1)
}
func main() {
//fun(0)
// i := Fibonacci(4)
// fmt.Println(i)
fmt.Println(JumpFloor(4))
fmt.Println(JumpFloor1(4))
}
经典跳台阶问题:青蛙一次可以跳1级台阶或者跳2级,问n级台阶,青蛙有多少种跳法。
从前四个就可以直接看出规律:从第三级开始,每一级的方案数是前两级方案数的和。那就很简单了,Fibonacci的方法罢了。
func JumpFloor2(n int) int {
if n == 1 || n == 2 {
return n
}
i, j := 1, 2
for p := 3; p <= n; p++ {
tmp := i + j
i = j
j = tmp
}
return j
}
最大连续子树和:即找最大值问题,我们也可以用动规,由于我用的是Go需要先写一个求最大值的方法
func Max(i, j int) int {
if i >= j {
return i
} else {
return j
}
}
然后,此方法将原数组的各个数值改变,如果不想改变可以重新创建一个数组保存每一次的结果。
func FindMax(arr []int) int {
result := 0
if len(arr) == 0 {
return result
}
result = arr[0]
for i := 1; i < len(arr); i++ {
arr[i] = Max(arr[i-1]+arr[i], arr[i])
result = Max(arr[i], result)
}
return result
}
01背包问题:
func main() {
w := []int{0, 2, 3, 4, 5}
v := []int{0, 3, 4, 5, 6}
Bigv := 8
result := [5][9]int{{0}}
for i := 1; i <= 4; i++ {
for j := 1; j <= Bigv; j++ {
if j < w[i] {
result[i][j] = result[i-1][j]
} else {
result[i][j] = Max(result[i-1][j], result[i-1][j-w[i]]+v[i])
}
}
}
fmt.Println(result)
}