Algorithm 在这样一座塔中找到尽可能多的人

Algorithm 在这样一座塔中找到尽可能多的人,algorithm,Algorithm,首先,让我们看看这个问题 一个马戏团正在设计一个由站在彼此头顶上的人组成的塔式表演 肩膀。出于实用和审美的原因,每个人都必须比他或她下面的人矮和轻。考虑到马戏团中每个人的身高和体重,写一个计算最大可能人数的方法 在这样一座塔里 EXAMPLE: Input: (ht, wt): (65, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68, 110) Output: The longest tower is length 6 and in

首先,让我们看看这个问题

一个马戏团正在设计一个由站在彼此头顶上的人组成的塔式表演 肩膀。出于实用和审美的原因,每个人都必须比他或她下面的人矮和轻。考虑到马戏团中每个人的身高和体重,写一个计算最大可能人数的方法 在这样一座塔里

EXAMPLE:
Input:
        (ht, wt): (65, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68, 110)
Output: The longest tower is length 6 and includes from top to bottom: 
        (56, 90) (60,95) (65,100) (68,110) (70,150) (75,190)
但我不太理解以下解决方案:

本书提出的解决方案:

  • 第一步。按高度对所有项目进行排序 首先,然后是重量。这意味着 如果所有的高度都是独一无二的, 然后,项目将按 他们的身高。如果高度是最重要的 同样,项目将按其属性进行排序 重量。示例:»»排序前: (60, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68,110). »之后 分类:(56,90)、(60,95), (60,100), (68, 110), (70,150), (75190)
  • 第二步。查找最长序列 其中包含不断增加的高度和 增加重量。为此,我们:

  • a) 从文件的开头开始
    序列目前,max_序列是 空的

  • b) 如果,对于下一个项目,
    身高和体重并没有增加 与上一项相比,我们
    将此项目标记为“不适合”

    c) 如果 找到的序列包含的项多于 “最大序列”,则变为“最大序列” 顺序”

  • d) 在那之后,搜索就结束了 从“不适合项”重复,
    直到我们到达终点
    原始序列

    public class Question {
    ArrayList<HtWt> items;
    ArrayList<HtWt> lastFoundSeq;
    ArrayList<HtWt> maxSeq;
    
    
    / Returns longer sequence
    ArrayList<HtWt> seqWithMaxLength(ArrayList<HtWt> seq1, ArrayList<HtWt> seq2) {
        return seq1.size() > seq2.size() ? seq1 : seq2;
    }
    
    
    // Fills next seq w decreased wts&returns index of 1st unfit item.
    int fillNextSeq(int startFrom, ArrayList<HtWt> seq) {
      int firstUnfitItem = startFrom;
      if (startFrom < items.size()) {
          for (int i = 0; i < items.size(); i++) {
            HtWt item = items.get(i);
            if (i == 0 || items.get(i-1).isBefore(item)) {
                seq.add(item);
            } else {
                firstUnfitItem = i;
            }
          }
      }
      return firstUnfitItem;
    }
    
    
    // Find the maximum length sequence
    void findMaxSeq() {
      Collections.sort(items);
      int currentUnfit = 0;
      while (currentUnfit < items.size()) {
          ArrayList<HtWt> nextSeq = new ArrayList<HtWt>();
          int nextUnfit = fillNextSeq(currentUnfit, nextSeq);
          maxSeq = seqWithMaxLength(maxSeq, nextSeq);
          if (nextUnfit == currentUnfit) 
            break;
          else 
            currentUnfit = nextUnfit;
      }
    }
    
    公开课问题{
    数组列表项;
    ArrayList lastFoundSeq;
    ArrayList maxSeq;
    /返回更长的序列
    ArrayList seqWithMaxLength(ArrayList seq1,ArrayList seq2){
    返回seq1.size()>seq2.size()?seq1:seq2;
    }
    //填充下一个序列,减少第一个不合适项目的wts和退货索引。
    int fillNextSeq(int startFrom,ArrayList seq){
    int firstUnfitem=从开始;
    if(从
    }

    问题:

    1> 函数fillNextSeq的用法是什么? 2> 为什么要选中“items.get(i-1).isBefore(item)”而不是将当前项与序列中的最新项进行比较

根据fillNextSeq函数,假设排序列表为(1,5)、(2,1)、(2,2)

首先(1,5)将被推入序列中。如果(2,1)项的重量小于(1,5),则不会将(2,1)项推入序列b/c。接下来,由于(2,1)在(2,2)之前,所以(2,2)将被推入序列中

public class Question {
ArrayList<HtWt> items;
ArrayList<HtWt> lastFoundSeq;
ArrayList<HtWt> maxSeq;


/ Returns longer sequence
ArrayList<HtWt> seqWithMaxLength(ArrayList<HtWt> seq1, ArrayList<HtWt> seq2) {
    return seq1.size() > seq2.size() ? seq1 : seq2;
}


// Fills next seq w decreased wts&returns index of 1st unfit item.
int fillNextSeq(int startFrom, ArrayList<HtWt> seq) {
  int firstUnfitItem = startFrom;
  if (startFrom < items.size()) {
      for (int i = 0; i < items.size(); i++) {
        HtWt item = items.get(i);
        if (i == 0 || items.get(i-1).isBefore(item)) {
            seq.add(item);
        } else {
            firstUnfitItem = i;
        }
      }
  }
  return firstUnfitItem;
}


// Find the maximum length sequence
void findMaxSeq() {
  Collections.sort(items);
  int currentUnfit = 0;
  while (currentUnfit < items.size()) {
      ArrayList<HtWt> nextSeq = new ArrayList<HtWt>();
      int nextUnfit = fillNextSeq(currentUnfit, nextSeq);
      maxSeq = seqWithMaxLength(maxSeq, nextSeq);
      if (nextUnfit == currentUnfit) 
        break;
      else 
        currentUnfit = nextUnfit;
  }
}
现在,序列包含(1,5)和(2,2),这是不正确的b/c(1,5)的权重大于(2,2)


谢谢你

使用fillNextSeq是为了在你的团队中获取下一个增加身高/体重的序列。它通过向ArrayList seq添加连续的项来实现这一点,直到遇到一个更胖或更高的人

items.get(i-1).isBefore(item)
的功能是检查下一个人是否比当前人矮、轻。请记住,您已经按身高和体重对人员进行了排序,因此,如果序列中的下一个人比当前人高或重,则他们将在排序数组中位于当前人之前。因此,所讨论的行是将当前项与序列中的最新项进行比较,它只是通过比较它们在排序数组中的位置来进行比较


希望这有帮助,祝你好运

我想我们可以用动态规划来解决这个问题。以下是我的想法:

L(j) -- the largest possible people ending at j ( 0 < j < n)
L(j) = max { L(i) } + 1 where i<j && ht(i)< ht(j) && wt(i)< wt(j)
we're looking for max{L(j)} where 0<j<n.
L(j)——以j(0L(j)=max{L(i)}+1,其中i我用c#写了一个有两部分的解

第1部分:-创建一个比较器,根据身高和体重(身高和体重)按升序排序

第2部分:-从末尾开始对排序数组进行线性搜索,使a[i]在身高和体重方面都小于a[i-1]

下面是代码。我有一些单元测试用例,并检查了代码是否正常工作。但我觉得这个解决方案中隐藏着一个bug请此处的专家验证代码。

实现IComparer的MyPerson类

public class Person : IComparer<Person>
{

    public double Height { get; set; }
    public double Weight { get; set; }

    public int Compare(Person p1, Person p2)
    {

        if ((p1.Height > p2.Height) && (p1.Weight > p2.Weight))
            return 1;

        return -1;
    }

}
公共类人员:IComparer
{
公共双倍高度{get;set;}
公共双权重{get;set;}
公共整数比较(人员p1、人员p2)
{
如果((p1.高度>p2.高度)和&(p1.重量>p2.重量))
返回1;
返回-1;
}
}
我的主要方法

public int NumberOfPeople(Person[] p)
    {

        if (p == null || p.Length == 0)
            return -1;

        Array.Sort(p, new Person());
        int last = p.Length - 1;
        int count = 1;
        for (int i = p.Length - 2; i >= 0 ; i--)
        {
            if ((p[i].Height < p[last].Height) && p[i].Weight < p[last].Weight)
            {
                last = i;
                count++;
            }
        }
        return count;
    }
public int NumberOfPeople(Person[]p)
{
if(p==null | | p.Length==0)
返回-1;
Sort(p,newperson());
int last=p.长度-1;
整数计数=1;
对于(int i=p.长度-2;i>=0;i--)
{
如果((p[i]。身高

任何形式的帮助都将不胜感激。

这被称为最长递增子序列问题。另外请注意,身高和体重是可以互换的(你可以先按体重排序)。如果你抄袭教科书“破解编码面试”中的一个问题,你至少必须引用它-1你好,拉斯科尔尼科夫,谢谢你的邀请