【问题标题】:Algorithm for "Circus tower"“马戏团塔”的算法
【发布时间】:2016-07-05 01:59:25
【问题描述】:

这是“破解编码面试”一书中的问题:

马戏团正在设计一个由站在彼此之上的人组成的塔式程序 肩膀。出于实用和审美的原因,每个人都必须比他或她下面的人更矮更轻。给定马戏团中每个人的身高和体重,编写一个计算最大可能人数的方法 在这样的塔中。

示例:

输入:

(ht, wt): (65, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68, 110) 

输出:

最长的塔长6,从上到下包括:

(56, 90) (60,95) (65,100) (68,110) (70,150) (75,190)

这是书中的解决方案:

“当我们把这个问题的绒毛剪掉后,我们就可以理解问题真的是下面这个问题。

我们有一个成对的项目列表。找到最长的序列,使得第一项和第二项都按非递减顺序。"

我想出了这个例子:

      {1,1} 
   {3,3} {7,2}
{6,4} {9,9} {8,5}

在这里,序列的值不是按非递减顺序排列的,但它仍然是一个有效的塔。而且我找不到将相同物品组织到另一个塔中的方法,该塔中的物品将按非递减顺序排列。我相信没有这样的方法。所以在我看来,解决方案是不正确的。

我错过了什么吗?

提前致谢。

【问题讨论】:

  • 这些值不是非递减顺序 => 它不是一个有效的塔 - 根据定义,根据问题文本。是什么让你说它是有效的?
  • 在 {3,3} -> {7,2}, 2
  • @Blorgbeard {1,1} 位于 {3,3} 和 {7,2} 之上; {3,3} 位于 {6,4} 和 {9,9} 之上,而 {7,2} 位于 {9,9} 和 {8,5} 之上。
  • @Blorgbeard 没关系,我现在看到这个问题从来没有说过每个人下面站着两个人 :) 我知道我错过了一些东西。谢谢!

标签: algorithm dynamic-programming


【解决方案1】:

不,您的值不是按非递减顺序排列的。正如@MooseBoys 评论所说,在您的情况下,第三个值的权重大于第二个。 ({3,3} -> {7,2}, 2

问题是最长递增子序列 (LIS) (DP) 略有变化。

您可以根据高度对元素进行排序,然后应用在重量上找到最长的递增子序列。

请在下面找到java实现:

class Person implements Comparable<Person> {
    int height;
    int weight;

    public Person(int height, int weight) {
        this.height = height;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Person{" +
                "height=" + height +
                ", weight=" + weight +
                '}';
    }

    @Override
    public int compareTo(Person p) {
        if(this.height>p.height) {
            return 1;
        } else if(this.height < p.height) {
            return -1;
        } else {
            return 0;
        }
    }
}

public class CircusTower {

    public void calculatePeople(Person[] input) {

        int weightArray[] = new int[input.length];
        String[] output = new String[input.length];
        for (int i=0;i<input.length;i++) {
            weightArray[i] = 1;
            output[i] = input[i].toString() + "";
        }
        int maxLength = 0;

        for (int i=1;i<input.length;i++) {
            for (int j=0;j<i;j++) {
                if( weightArray[j]+1>weightArray[i] && input[i].weight>input[j].weight) {
                    weightArray[i] = weightArray[j] + 1;
                    output[i] = output[j] + " " + input[i].toString();
                    if(maxLength<weightArray[i]) {
                        maxLength = weightArray[i];
                    }
                }
            }
        }

        System.out.println();


        for (int i = 0; i < input.length; i++) {
            if (weightArray[i] == maxLength) {
                System.out.println("Longest Increasing subsequence - " + output[i] + " of length = " + maxLength);
            }
        }

    }

    public static void main(String[] args) {
        CircusTower ct = new CircusTower();
        Person p1 = new Person(65,100);
        Person p2 = new Person(70,150);
        Person p3 = new Person(56, 90);
        Person p4 = new Person(75, 190);
        Person p5 = new Person(60, 95);
        Person p6 = new Person(68, 110);

        Person[] array = new Person[]{p1,p2,p3,p4,p5,p6};

        Arrays.sort(array);

        ct.calculatePeople(array);

    }

}

我用的是LIS问题的n square实现,U也可以用nlogn中比较好的。

希望它澄清。

【讨论】:

  • 感谢您的回答!我编辑了我的问题,以便更清楚地了解塔的建造方式。 {1,1} 位于 {3,3} 和 {7,2} 之上; {3,3} 位于 {6,4} 和 {9,9} 之上,而 {7,2} 位于 {9,9} 和 {8,5} 之上
  • 没关系,我现在看到这个问题从来没有说过每个人下面站着两个人 :) 我知道我错过了一些东西。谢谢!
猜你喜欢
  • 2019-09-29
  • 2019-08-19
  • 2017-04-17
  • 1970-01-01
  • 2013-04-27
  • 2018-12-03
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多