【问题标题】:Christmas Eve problem:dynamic-programming平安夜问题:动态规划
【发布时间】:2020-12-13 23:58:25
【问题描述】:

在平安夜,艾莉决定去她所在地区的每一所房子里寻求捐款,以筹集 X 单位的钱。

在每所房子里,她都会询问她需要的剩余金额。除了第一所房子给出0到X之间的随机数量外,每所房子都比之前房子给出的最小金额要少。

她所在的地区共有 Y 间房子 她只访问这些房子,直到她总共获得 x 个单位的钱。她用多少种方式从 Y 家房子里凑齐 x 单位的钱?

输入规范

input1: X 她需要的总金额。

input2:她所在地区的 Y 栋房屋

示例 1:

输入1:5

输入2:5

输出:3

说明: 3 种可能的方式,5 个来自第一宫或 4 个来自第一宫和 1 个来自第二宫或 3 个来自第一宫和 2 个来自第二宫。

.......................

我无法构建编写代码的逻辑。如果您知道解决方案,请帮助!我从过去 2 天开始尝试这个。

【问题讨论】:

  • 在您描述的 Example1 中,您的意思是 input2 是 2,而不是 5?我不明白为什么只有两个房子参与你为那个例子描述的解决方案。

标签: algorithm recursion data-structures dynamic-programming knapsack-problem


【解决方案1】:

致电W(X,Y,C)Y的房屋数量中收集金额X的方式,知道每个房屋最多会给C

(您的问题最初是C=X;所以您要寻找的解决方案是W(X,Y,X)。)

现在假设你得到了XYC。考虑第一个房子给出的A 的数量。 A 可以是[0,C] 范围内的任何数字。对于A的每一个选择,与剩余房子的总和的方法数是W(X-A, Y-1, min(A-1, X-A)),因为:在第一个房子给A之后要收集的剩余金额是X-A;剩余房屋数量为Y-1;其他房子将给予少于A(所以最多A-1),最多X-A,因为这是要收集的剩余金额。

这给你一个重复关系:W(X,Y,C) = sum for A in [0..C] of: W(X-A, Y-1, min(A-1, X-A))

您还可以算出基本情况:W(0,Y,C) = 1,因为只有一种方法可以给出 0。W(X,0,C) = 0 如果X 不为零,因为如果没有房子,那么钱就无法收回。 W(X, 1, C) = 1 如果C >= X 因为只有一种方式可以让一所房子单独捐出所有的钱。 W(X, 1, C) = 0 if C

您可以使用递归关系和基本情况以经典动态编程方式填充数组。那么您正在寻找的答案将在单元格 W(X,Y,X) 中。

二维数组可能有更聪明的方法,它只依赖于 (X,Y) 而不是 (X,Y,C),但约束条件是“每个房子提供的数量少于之前的房子给出的最小数量" 让它变得更复杂。

【讨论】:

    【解决方案2】:

    我记得很久以前的一个 java 测试中的这个问题。如果您了解这个动态规划问题的性质及其递归性质,那就很容易了。

    public class Example2 {
    
        // this will be the solution
        static int solutionCount = 0;
    
    
    
        public static void canCollect(int remainingAmount, int remainingHouses, int previousAmount) {
    
            if (remainingHouses == 0)
                return;
    
            if (remainingAmount < 0)
                return;
    
            if (remainingAmount == 0) {
                solutionCount++;
                return;
            }
    
            for (int i = 1; i < previousAmount; i++) {
                //deduct amount collected from this house-visit (i), deduct 1 from remaining houses, and set previousAmount to what you are collecting here
                canCollect(remainingAmount - i, remainingHouses - 1, i);
            }
    
        }
        
        
        // This is your solution function, although you'll need to change it enough to satisfy test-cases.
        public static int solutionFunction(int x, int y) {
            for (int i = 0; i <= x; i++) {
                canCollect(x - i, y-1, i);
            }
            return solutionCount;
        }
    
        
        //main is just to execute it here. Omit it in your submission
        public static void main(String args[]) {
            System.out.println(solutionFunction(5,5)); //3
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-10-17
      • 2012-04-09
      • 2011-10-14
      • 1970-01-01
      • 2021-02-25
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多