UVa 10134:越大越聪明吗? (动态规划和最长递增子序列)

发布于 2024-11-03 05:20:45 字数 1279 浏览 4 评论 0原文

private void findLDS() {
    Integer[] array = Arrays.copyOf(elephants.iq, elephants.iq.length);
    Hashtable<Integer, Integer> eq = elephants.elephantiqs;

    Integer[] lds = new Integer[array.length];
    Integer[] prev= new Integer[array.length];
    lds[0] = 0;
    prev[0] = 0;

    int maxlds = 1, ending=0;

    for(int i = 0; i < array.length; ++i) {
        lds[i] = 1;
        prev[i] = -1;

        for (int j = i; j >= 0; --j) {
            if(lds[j] + 1 > lds[i] && array[j] > array[i] && eq.get(array[j]) < eq.get(array[i])) {
                lds[i] = lds[j]+1;
                prev[i] = j;
            }
        }
        if(lds[i] > maxlds) {
            ending = i;
            maxlds = lds[i];
        }
    }
    System.out.println(maxlds);
    for(int i = ending; i >= 0; --i) {
        if(prev[i] != -1) {
            System.out.println(eq.get(array[prev[i]])); 
        }

    }

我将此算法基于这个SO问题。该代码试图找到最长的递减子序列而不是递增子序列。 array[] 按降序排序,我还有一个哈希表,其中大象的智商作为其权重的键。

我很难正确理解 DP,我需要一些帮助。

除了跟踪 prev[] 中所选的序列(它总是丢失一个元素)之外,我的算法似乎工作得很好。有谁知道该怎么做?

private void findLDS() {
    Integer[] array = Arrays.copyOf(elephants.iq, elephants.iq.length);
    Hashtable<Integer, Integer> eq = elephants.elephantiqs;

    Integer[] lds = new Integer[array.length];
    Integer[] prev= new Integer[array.length];
    lds[0] = 0;
    prev[0] = 0;

    int maxlds = 1, ending=0;

    for(int i = 0; i < array.length; ++i) {
        lds[i] = 1;
        prev[i] = -1;

        for (int j = i; j >= 0; --j) {
            if(lds[j] + 1 > lds[i] && array[j] > array[i] && eq.get(array[j]) < eq.get(array[i])) {
                lds[i] = lds[j]+1;
                prev[i] = j;
            }
        }
        if(lds[i] > maxlds) {
            ending = i;
            maxlds = lds[i];
        }
    }
    System.out.println(maxlds);
    for(int i = ending; i >= 0; --i) {
        if(prev[i] != -1) {
            System.out.println(eq.get(array[prev[i]])); 
        }

    }

I have based this algorithm on this SO question. This code is trying to find longest decreasing subsequence instead of increasing. array[] is sorted in descending order, and I also have a hashtable with the elephants IQ's as keys for their weights.

I'm having a hard time properly understanding DP, and I need some help.

My algorithm seems to work fine besides tracking the chosen sequence in prev[], where it always misses one element. Does anyone know how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

虫児飞 2024-11-10 05:20:45

解决这个问题的几种方法:

  1. 按权重降序排序,然后找到最长的递增子序列。
  2. 按 IQ 降序排序,然后找到权重的最长递增子序列。
  3. 和4.只是(1)和(2),交换单词“增加”和“减少”

如果你不理解最长增加子序列O(N^2)的DP,它基本上是这样的:

  1. 因为列表有无论如何,要严格增加/减少,您可以预先消除一些大象以使集合独一无二。
  2. 创建一个数组,我将其称为llis,代表“最长递增子序列”,长度为N,即现在大象的数量。创建另一个名为 last 且长度相同的数组。我假设大象的排序列表称为数组,就像您的问题陈述中一样。
  3. 假设您已经按降序对大象进行了排序,您将需要找到最长的智商递增子序列。
  4. 告诉自己数组 llis 中索引 n 的元素(这是一个不同的“n”)< N 将是 array 子数组从索引 0 到 n(含)的最长递增子序列的长度。还可以说 next 数组中索引 n 处的元素将是 array 中最长递增子序列的下一个索引。
  5. 因此,要找到 0 到 N - 1(包括整个数组)的“子数组”中最长递增子序列的长度,只需要找到 N - DP 计算后数组 llis 中的第 1 元素,查找实际子序列将简化为遵循 next 数组中的索引。
  6. 现在您知道了要查找的内容,就可以继续使用该算法了。在数组中的索引n处,你如何知道最长的递增子序列是什么?好吧,如果您已经计算了每个 k < 的最长递增子序列的长度以及子序列中的最后一个值。 n,如果大象的智商n,您可以尝试将索引n处的大象添加到以k结尾的最长递增子序列中k 大象的智商还要高。在这种情况下,以大象 n 结尾的最长递增子序列的长度将为 llis[k] + 1。 (另外,请记住将 next[k] 设置为 n,因为递增子序列中的下一个大象将是 n 处的大象。 )
  7. 我们找到了 DP 关系 llis[n] = max(llis[n], llis[k] + 1),在遍历了所有 k 后,严格之前n。只需以正确的顺序(线性)处理 n ,您就应该得到正确的结果。
  8. 过程/警告: 1) 按从 0 到 N - 1 的顺序处理 n。 2) 对于每个n,按从n - 1到0的顺序处理k,因为您希望最小化k > 你选择的。 3) 处理完成后,请务必找到数组 llis 中的最大数字以获得最终结果。
  9. 由于这被标记为家庭作业,我不会明确说明如何修改它以找到最长递减子序列,但我希望我的解释有助于您对 DP 的理解。如果您选择使用它,您自己应该很容易找出递减版本。 (请注意,可以使用递增版本来解决此问题,如方法 1 或 2 中所述。)

A few ways to approach this one:

  1. Sort by weight in decreasing order, then find the longest increasing subsequence.
  2. Sort by IQ in decreasing order, then find the longest increasing subsequence of weights.
  3. and 4. are just (1) and (2), switching the words "increasing" and "decreasing"

If you don't understand the DP for longest increasing subsequence O(N^2), it's basically this:

  1. Since the list has to be strictly increasing/decreasing anyway, you can just eliminate some elephants beforehand to make the set unique.
  2. Create an array, which I will call llis standing for "Longest Increasing Subsequence", of length N, the number of elephants there now are. Create another array called last with the same length. I will assume the sorted list of elephants is called array as it is in your problem statement.
  3. Assuming that you've already sorted the elephants in decreasing order, you will want to find the longest increasing subsequence of IQs.
  4. Tell yourself that the element in the array llis at index n (this is a different "n") < N will be the length of the longest increasing subsequence for the sub-array of array from index 0 to n, inclusive. Also say that the element in the next array at index n will be the next index in array in the longest increasing subsequence.
  5. Therefore, finding the length of the longest increasing subsequence in the "sub-array" of 0 to N - 1 inclusive, which is also the whole array, would only require you to find the N - 1 th element in the array llis after the DP calculations, and finding the actual subsequence would simplify to following the indices in the next array.
  6. Now that you know what you're looking for, you can proceed with the algorithm. At index n in the array, how do you know what the longest increasing subsequence is? Well, if you've calculated the length of the longest increasing subsequence and the last value in the subsequences for every k < n, you can try adding the elephant at index n to the longest increasing subsequence ending at k if the IQ of the elephant n is higher than the IQ of the elephant at k. In this case, the length of the longest increasing subsequence ending at elephant n would be llis[k] + 1. (Also, remember to set next[k] to be n, since the next elephant in the increasing subsequence will be the one at n.)
  7. We've found the DP relation that llis[n] = max(llis[n], llis[k] + 1), after going through all k s that come strictly before n. Just process the n s in the right order (linearly) and you should get the correct result.
  8. Procedure/warnings: 1) Process n in order from 0 to N - 1. 2) For every n, process k in order from n - 1 to 0 because you want to minimize the k that you choose. 3) After you're done processing, make sure to find the maximum number in the array llis to get your final result.
  9. Since this is tagged as homework, I won't explicitly say how to modify this to find the longest decreasing subsequence, but I hope my explanation has helped with your understanding of DP. It should be easy to figure out the decreasing version on your own, if you choose to use it. (Note that this problem can be solved using the increasing version, as described in approaches 1 or 2.)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文