当前位置: 首页 > 知识库问答 >
问题:

动态规划问题-扩展以找到所有可能的求和路径

祁烨
2023-03-14

我正在做一个DP课程来复习(这很好,帮了我很多),其中一个问题是给定一个目标和一个数字列表,是否有一条通往目标的路径/最佳(最短)路径是什么

我已经解决了路径存在最佳路径问题,但一直在思考一个他们没有要求解决方案的问题-你能列出解决方案的所有路径吗:

下面是golang代码

戈兰

func BestSum(ts int, nums []int) []int {
    var best []int
    return bs(ts, nums, best)
}

func bs(ts int, nums, best []int) []int {
    if ts == 0 {
        return []int{}
    } else if ts < 0 {
        return nil
    }

    for _, n := range nums {
        rc := bs(ts-n, nums, best)
        if rc != nil {
            path := append(rc, n)
            if best == nil || len(best) > len(path){
                best = path
            }           
        }
    }

    return best
}

//例如:BestSum(7,[5,3,4,7])//ans:[7]

既然我们在这里覆盖了所有路径,我想看看是否可以返回所有路径,但我陷入了一个逻辑:

func AllSum(ts int, nums []int) [][]int {
    all := [][]int{}

    var as func(int, []int) []int 
    as = func(s int, nums []int) []int {
        if s == 0 {
            return []int{}
        } else if s < 0 {
            return nil
        }
    
        var path []int
        for _, n := range nums {
            rc := as(s-n, nums)
            if rc != nil {
                path = append(rc, n)
// this section iterates over path so far each time (slow) and sums to see if it can append yet
                var sum int
                for _, c := range path {
                    sum+=c
                }
                if sum == ts {
                    all = append(all, path)
                }
            }
        }
    
        return path
    }

    _ = as(ts, nums)
    return all
} 

上面的代码传递给7,[5,4,3,7],但对于20,[2,10]缺少[2,2,2,2,2,2,2,2,2,2]失败

是否有一种众所周知的模式可以递归地从函数生成路径中收集所有路径?


共有2个答案

葛磊
2023-03-14

仅供参考,上面发布的解决方案给出了不正确的答案,DP课程实际上继续解释了一个类似问题的解决方案,这让我找到了这个问题的解决方案:

func AllSum(ts int, nums []int) [][]int {
    return as(ts, nums)
} 

func as(s int, nums []int) [][]int {
    if s == 0 {
        return [][]int{{}}
    }
    
    var all [][]int
    for _, n := range nums {
        if s-n < 0{
            continue
        }

        paths := as(s-n, nums)
        for i, _ := range paths {
            paths[i] = append(paths[i], n)
            all = append(all, paths[i])
        }
    }

    return all
}

链接到固定代码:https://play.golang.org/p/cpEKgV2e1kM

吴欣然
2023-03-14

当前算法的问题是递归函数只能返回一个可能的解;例如,当它到达12、[2 2]时,有多个解决方案(包括[2 2 2 10 2][2,2,2,2,2,2,2,2]),但只返回一个(检查所有路径,但许多结果被丢弃)。

一种常见的解决方案是将路径传递给递归函数;例如:

package main

import (
    "fmt"
)

func main() {
    fmt.Println(AllSum(20, []int{2, 10}))
    fmt.Println(AllSum(7, []int{5,4,3,7}))
}

func AllSum(ts int, nums []int) [][]int {
    return allSum(ts, nums, nil)
}

func allSum(s int, nums []int, path []int) [][]int {
    if s < 0 {
        return nil // No solution here
    }
    if s == 0 { // solution found
        return [][]int{path}
    }
    
    // Copy the path to avoid editing other solutions
    p := make([]int, len(path))
    copy(p, path)
    
    var solutions [][]int
    for _, n := range nums {
        rc := allSum(s-n, nums, append(p, n))
        if rc != nil {
            solutions = append(solutions, rc...)
        }
    }
    return solutions
}

游乐场

 类似资料:
  • 如果一个问题的最优解可以通过贪婪得到,那么它也可以通过动态规划得到吗?既然贪婪和dp都在处理子问题的最优解,那么可以说dp可以解决贪婪可以解决的所有问题吗?

  • 我在理解各种问题的动态规划解决方案方面存在问题,特别是硬币兑换问题: “给定一个值N,如果我们想换N美分,并且我们有无限多个S={S1,S2,…,Sm}值的硬币,我们可以用多少种方式来换?硬币的顺序并不重要。 例如,对于N=4和S={1,2,3},有四种解决方案:{1,1,1},{1,1,2},{2,2},{1,3}。所以输出应该是4。对于N=10和S={2,5,3,6},有五个解:{2,2,2,

  • 几天前,我在读关于分数背包问题的贪婪算法和动态规划的书,我发现这个问题可以用贪婪方法得到最优解。谁能给出一个例子或解决方案来解决这个问题的动态规划方法? 我知道贪婪方法是解决这个问题的最好方法,但我想知道动态规划是如何解决这个问题的。

  • 我有点卡住了,我决定试试这个问题https://icpcarchive.ecs.baylor.edu/external/71/7113.pdf 为了防止它404'ing这里是基本的任务 编辑:我这么做纯粹是出于好奇。除了挑战自己,我不需要出于任何特殊原因去做这项任务 基本上,它是从一个数组中构建一个稀疏图,该图是无向的,并且由于-d的对称性。。。d跳跃,它也可以是一个完整的图(包括所有边)或相互不

  • 动态规划 动态规划 Dynamic Programming,核心思想就是将大问题划分成小问题进行解决,从而一步一步的获得最优解的处理算法 动态规划跟分治算法思想类似,但动态规划算法会依赖到上一次计算的结果,每次求解是建立在上一次子阶段的结果基础之上进一步处理,而分治算法分解出来问题往往是独立的 动态规划一般可以通过填表的方式进行逐步推进得到最优解 0/1背包问题 01背包问题是经典的利用动态规划算

  • 我正在练习动态编程,我正在努力调试我的代码。这个想法是在给定一组数字的情况下找出求和是否可能。这是我的代码: 以下是输出: 据我所知,在我的fe语句中,算法应该向上1行,然后查看x和y的差异并检查该槽是否可能。例如,在最明显的情况下,最后一行的最后一个元素。那将是10(y)-11(x),它应该一直回到它上面一行的索引1,我们知道这是True。不完全确定我做错了什么,如果能帮助理解这一点,将不胜感激