圣诞平安夜问题:动态编程

问题描述

圣诞节前夕,艾莉决定去她所在地区的每所房屋并要求捐款,以收取X单位的钱。

在每所房子,她要求剩余的钱。除了第一座房屋的随机数介于0到X之间之外,每座房屋的收益均低于前几座房屋的最小值。

她所在的地区总共有Y栋房屋。她只参观这些房屋,直到获得总计x单位的钱为止。她以几种方式从Y座房屋中收取了x单位的钱?

输入规范

投入1:X所需的总金额。

input2:她所在地区共有Y栋房屋

示例1:

input1:5

input2:5

输出:3

说明: 3种可能的方式,从第一所房子5处,或从第一所房子4处,从第二所房子1处,从第一所房子3处,从第二所房子2处,2处。

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

我无法建立编写代码的逻辑。如果您知道解决方案,请提供帮助!我从最近两天开始尝试这种方法

解决方法

请致电W(X,Y,C),从数量X的房屋中收取Y的数量,知道每个房屋最多可以给C

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

现在假设给您XYC。考虑一下第一所房子给的AA可以是[0,C]范围内的任何数字。对于A的每种选择,用剩余房屋完成总和的方式为W(X-A,Y-1,min(A-1,X-A)),因为:在第一所房屋给定A之后,要收取的剩余金额为{{1 }};剩余的房屋数量为X-A;其他房屋的捐款将少于Y-1(因此最多A)和最多A-1,因为这是要收集的剩余金额。

这为您提供了重复关系:X-A

您还可以找出基本情况:W(X,C) = sum for A in [0..C] of: W(X-A,X-A)),因为只有一种方法可以得出0。W(0,C) = 1如果W(X,C) = 0为非零,因为如果没有房屋,那么钱不能收。 X是否为W(X,1,C) = 1,因为只有一所房子可以独享全部金钱。 C >= X如果C

您可以使用递归关系和基本案例以经典的动态编程方式填充数组。然后,您要查找的答案将在单元格W(X,C) = 0中。

可能存在一种更聪明的方法,即仅依赖于(X,Y)而不是(X,Y,C)的二维数组,但是约束条件“每所房屋所提供的数量少于先前房屋所提供的最小数量”使其变得更加复杂。

,

我记得这个问题来自我很久以前的 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
    }

}