苹果采摘优化算法

问题描述

我发现了以下问题:假设我有N个苹果树的字段,每个字段上都带有A i 苹果。我也有M个购物篮,每个购物篮的属性C i 用于容纳容量,而F i 用于灵活性。当我要采摘苹果树时,我只能按从1到N的顺序从树中采摘。在每棵树上,我有两个选择,可以采摘树上的所有苹果或扩大篮子以使其容量增加F 。当我展开篮子时,我无法在那棵树上摘水果。找出每个篮子可以采摘的苹果的最大数量

示例:

N = 5; A = [3,2,4,7,5]

M = 2; (C,F)= [(5,3),(3,6)]

答案: 对于第一个篮子,最多可获取12个苹果:

  1. 将袋子扩大3(最大容量= 5 + 3 = 8)
  2. 将袋子扩大3(最大容量= 8 + 3 = 11)
  3. 将袋子扩大3(最大容量= 11 + 3 = 14)
  4. 摘第4棵树(得到7个苹果,当前总数= 7)
  5. 摘第5棵树(得到5个苹果,当前总数= 12)

第二个行李最大为15:

  1. 摘第1棵树(得到3个苹果,当前总数= 3)
  2. 将袋子扩大6(最大容量= 3 + 6 = 9)
  3. 将袋子扩大6(最大容量= 9 + 6 = 15)
  4. 摘第4棵树(获得7个苹果,当前总数= 10)
  5. 摘第5棵树(得到5个苹果,当前总数= 15)

我应该如何解决这个问题?

解决方法

我认为这是一个回溯问题。首先,我建议您检查一下该内容的一般说明。 https://en.wikipedia.org/wiki/Backtracking

如果需要在实际代码中实现算法,则可能会有更详细的回溯描述。

,

将这个问题视为递归关系会有所帮助:

enter image description here

假设有一个函数MaxApples(treeNum,capacityLeft),该函数可为您提供给定篮子最多可获得的苹果数量。

此功能的初始参数为treeNum = 0,因为您是从第一棵树开始的; capacityLeft = C for the given basket是因为购物篮为空且尚未扩展。

然后为每棵树有2个选择-展开篮子或摘树。这可以通过对MaxApple的2次递归调用来表示,在第一种选择中,您递增树号并以F扩展容量(这是篮子扩展的程度)。另一种选择是将当前树中的所有苹果添加到您的购物篮中,然后在递归调用中增加treeNum并减少容量(仅采摘量)。

注意:您必须在每个阶段检查是否可以选择。也就是说,检查CapacityLeft是否大于或等于您要选择的树。

您可以计算这两者的总和,并取其中的最大值。

以下是Java中的以下代码(仅适用于一个篮子):

class Main {

  static int[] trees = new int[]{3,2,4,7,5};
  static int basketCapacity = 5;
  static int basketFlex = 3;

  public static void main(String[] args) {
    System.out.println(maxApples(0,basketCapacity));
  }

  public static int maxApples(int treeNum,int capacityLeft) {
    if (treeNum >= trees.length) {
      return 0;
    }

    int pick = 0;
    if (trees[treeNum] <= capacityLeft) {
      pick = trees[treeNum] + maxApples(treeNum+1,capacityLeft - trees[treeNum]);
    }
    int expand = maxApples(treeNum+1,capacityLeft + basketFlex);

    return Math.max(pick,expand);
  }
}