繁体   English   中英

无法将此递归代码记忆到自上而下的 DP 中

[英]Not able to Memoize this Recursive Code into Top Down DP

我在我的一个测试中遇到了这个问题。 我为它写了一个递归解决方案(我在几个测试用例上试过了,它似乎工作正常)。 我正在尝试记住这段代码,但我做不到。

问题陈述是这样的,

您正在 IPL11 App 上玩 Fantasy Cricket。 该游戏与其他 Fantasy Cricket 应用程序略有不同。 此处为您提供了两个玩家列表。 两个列表都包含n玩家。 该列表是根据它们提供的值表示的。

您需要 select 这2*n玩家中正好有n个玩家。

选择需要根据以下规则进行。

  • 您可以从list1的末尾或list2的末尾拨打 select
  • 一旦您 select 成为玩家,他就会从该列表中删除。
  • 为了获得更好的球员,您还可以选择放弃球员并将其从列表末尾删除。 您最多可以执行 k 次丢弃操作。

自然地,您会希望在您的团队中获得最大价值。 根据以上规则,从 2 个列表中选出n玩家,求出你能得到的最大值。

例子

n: 6
list1: [10, 13, 31, 12, 12, 18]
list2: [34, 12, 3, 23, 11, 13]
k: 2
O/P: 112
Explanation:

* Select 18 (list1)
* Select 13 (list2)
* Skip 11 (list2)
* Select 23 (list2)
* Select 12 (list1)
* Skip 3 (list2)
* Select 12 (list2)
* Select 34 (list2)

我的递归解决方案,

public static int helper(int[] list1, int[] list2, int n1, int n2, int k, int count) {
        if(count == n) return 0;
        int chooseFromList1 = Integer.MIN_VALUE;
        int chooseFromList2 = Integer.MIN_VALUE;
        if(n1 > 0) {
            chooseFromList1 = list1[n1-1]+helper(list1, list2, n1-1, n2, k, count+1);
        }
        if(n2 > 0) {
            chooseFromList2 = list2[n2-1]+helper(list1, list2, n1, n2-1, k, count+1);
        }
        int temp = Integer.MIN_VALUE;
        if(k > 0) {
            int skipList1 = helper(list1, list2, n1-1, n2, k-1, count);
            int skipList2 = helper(list1, list2, n1, n2-1, k-1, count);
            temp = Math.max(skipList1, skipList2);
        }
        return Math.max(Math.max(chooseFromList1, chooseFromList2), temp);
    }

我所做的是,我在这个递归代码中做了 4 个选择,

  • 如果 n1 > 0,则从list1中取出最后一个元素
  • 如果 n2 > 0,则从list2中取出最后一个元素
  • 如果 k > 0,则跳过list1的最后一个元素
  • 如果 k > 0,则跳过list2中的最后一个元素

我想将它转换为自顶向下 DP,但无法为其编写代码。

天真地,给定列表对的记忆键将是[n1, n2, k, count] 这将产生工作代码。 由于数据结构是通过引用传递的,您可以简单地将缓存作为您的helper function 的参数。

但是需要多少memory呢? 好吧,给定起始条件, n1将有O(n) O(n)选择, n2将有 O(n) 个选择,传入的临时k将有O(k)个选择。所有这些都保存在 memory 中,对于O(kn^2) memory。和类似的步骤数。

如果我为比赛设置它,我会选择nk足够大,以至于这种天真的方法将用完 memory 和/或运行时间太长。 例如,将它们都设置为 1000,因此您在缓存中使用了千兆字节的 memory,并且必须调用 function 十亿次。

那你怎么能让它更有效率呢? 好吧,操作顺序并不重要。 从每个列表中,您将选择一定数量的项目,并丢弃一定数量的物品。 所以让你的助手 function 只分析一个列表。 现在对于每个列表,您需要O(kn)条数据,这些数据需要O(kn)的工作来生成。

一个聪明的自下而上的方法实际上可以在O(n) memory 和O(n log(n))时间内运行。 但这需要非常聪明和多堆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM