/*
从左往右的尝试模型1
规定1和A对应,2和B对应,3和C对应...
那么一个数字字符串比如“111”就可以转化为"AAA","KA","AK"
给定一个只有数字字符组成的字符串str,返回有多少种转化结果
11111
1 1111
11 111
111 不能转换
此题可以改成动态规划的解法
*/
func TestNumber(t *testing.T) {
fmt.Println(number("112"))
}
func number(str string) int {
if str == "" || len(str) == 0 {
return 0
}
return processNumber(str,0)
}
// str[0...i-1]上已经转化完了,固定了
// i 之前的位置,如何转化已经做过的决定了,不用再关心
// i... 有多少种转化的结果
func processNumber(str string,i int) int {
if i == len(str) { //base case
return 1 //没有字符的时候,可以转化为“” or 找到一种答案时,返回一种答案
}
if str[i] == '0' { //i 没有到终止位置, 0无法被转化
return 0
}
if str[i] == '1' { // str[i]字符不是’0‘
res := processNumber(str,i+1) // i自己作为单独的部分,后序有多少种方法
if i + 1 < len(str) {
res += processNumber(str, i + 2) //(i和i+1) 作为单独的部分,后序有多少种
}
return res
}
if str[i] == '2' {
res := processNumber(str,i+1) // i自己作为单独的部分,后序有多少种方法
if i + 1 < len(str) && str[i+1] >='0' && str[i+1] <= '6' { // i 和 i+1 作为单独的部分并且没有超过 26,后序有多少种方法
res += processNumber(str, i + 2) //(i和i+1) 作为单独的部分,后序有多少种
}
return res
}
// str[i] == '3' ~ '9'
return processNumber(str,i+1) //只有去i+1 位置 1种选择
}
/*
从左往右的尝试模型2 (背包问题)
给定两个长度都为N 的数组weights 和 values, N个货物 N个价值
weights[i] 和 values[i]分别代表i号物品的重量和价值。
给定一个整数bag,表示一个载重bag的袋子,
你装的物品不能超过这个重量。
返回你能装下最多的价值是多少。
*/
func GetMaxValue(w, v []int,bag int) {
processMaxValue(w,v,0,0,bag)
}
// 不变: w[] v[] bag
//index... 最大价值
//0... index - 1 上做了货物的选择,使得你已经达到的重量是alreadyW
//返回 -1 认为没有方案,否则认为返回的值是真实价值
func processMaxValue(w, v []int,index, alreadyW,bag int) int {
if alreadyW > bag {
return -1
}
if index == len(w) { //方案有效,index 往后的价值为0
return 0
}
p1 := processMaxValue(w,v,index + 1,alreadyW,bag) //没有要当前货
p2Next := processMaxValue(w,v,index + 1,alreadyW +w[index],bag) //要了当前货,后边货的最大价值
p2 := -1
if p2Next != -1 {
p2 = v[index] + p2Next
}
return Max(p1,p2)
}
func Max(a, b int) int {
if a < b {
return b
}
return a
}
func GetMaxValue2(w, v []int,bag int) {
processMaxValue2(w,v,0,bag)
}
// 只剩下rest的空间了
// index...货物自由选择,但是剩余空间不要小于0
// 返回能够获得的最大价值
func processMaxValue2(w, v []int,index ,rest int) int {
if rest <= 0 { // base case
return 0
}
// rest > 0
if index == len(w) { // base case 2
return 0
}
//有货也有空间
p1 := processMaxValue2(w,v,index + 1, rest)
p2 := math.MinInt
if rest >= w[index] {
p2 = v[index] + processMaxValue2(w,v, index+1,rest - w[index])
}
return Max(p1,p2)
}
递归——从左往右的尝试模型
于 2021-11-02 18:24:26 首次发布