Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 找到他们站在一起所能达到的最大高度?_Algorithm_Dynamic Programming_Greedy - Fatal编程技术网

Algorithm 找到他们站在一起所能达到的最大高度?

Algorithm 找到他们站在一起所能达到的最大高度?,algorithm,dynamic-programming,greedy,Algorithm,Dynamic Programming,Greedy,给出了n名男子的体重和他们的力量(他们能承受的最大重量)。所有的高度都是相同的。找到他们站在一起所能达到的最大高度? 这意味着,你必须通过从他们身上取下最大数量的人来安置他们,这样就不会有人比他的力量更重 这个问题困扰着我。首先我想用贪婪,先拿实力最大的人,但这并没有给出正确的答案。然后我试着解决它,就像背包一样,这也是不对的。我不能想出一个有效的算法。有人能帮忙吗?首先,对不起,我的英语:) 这里有一种方法,你可以认为是一种解决问题的方法 好吧,如果你可以假设每层楼都以统一的形式吸收全部重量,

给出了n名男子的体重和他们的力量(他们能承受的最大重量)。所有的高度都是相同的。找到他们站在一起所能达到的最大高度? 这意味着,你必须通过从他们身上取下最大数量的人来安置他们,这样就不会有人比他的力量更重


这个问题困扰着我。首先我想用贪婪,先拿实力最大的人,但这并没有给出正确的答案。然后我试着解决它,就像背包一样,这也是不对的。我不能想出一个有效的算法。有人能帮忙吗?

首先,对不起,我的英语:)

这里有一种方法,你可以认为是一种解决问题的方法

好吧,如果你可以假设每层楼都以统一的形式吸收全部重量,(我的意思是没有“一个人只能承受两个人的重量”之类的限制。 我们将从一个假设的结构开始,每层楼有一个人,通过这个结构,我们将开始检查限制并安排人员

我们将检查最底层(一层),我们将问:这层楼能承受所有高层楼的重量吗?
如果答案是否定的,我们从塔顶移除一个人,将其添加到该楼层,然后再次检查该楼层的重量状况。 如果答案是肯定的,我们通过检查下一层

之后,我们将有一个符合要求的结构。 C#代码:

int amountOfMens=n;
浮子重量=w;
浮子强度=s;
浮动高度=h;
int[]门西奈楼层;
公共无效MyAlg()
{
mensInEachFloor=newint[amountOfMens];//我们能达到的最大高度就是最大的男性数量。
对于(int i=0;i可支持的权重)
{
//从上面移走一个人
从最高楼层移除一名人员();
//在这一层加一个人来帮助减轻体重
增编(一);
}
其他的
{
//我们在这一层很好:)
floorOk=真;
}
}
}
Log(“塔的总高度为:“+GetTowerHeight());
}
高层专用浮球总重量(内部启动层)
{
浮动总重量=0;
对于(int i=起始楼层;i=0;i--)
{
//如果这层楼有一个或多个男人。。
if(mensInEachFloor[i]!=0)
{
//我们从地板上搬走
mensInEachFloor[i]=mensInEachFloor[i]-1;
//我们完成了
打破
}
}
}
专用void AddOneManToFloor(内部楼层)
{
//将一个人添加到所选楼层
mensInEachFloor[楼层]=mensInEachFloor[楼层]+1;
}
私有浮点GetTowerHeight()
{
//我们会数一数上面有男人的楼层数
浮点数=0;
对于(int i=0;i0)
{
//这意味着它是一个有效的楼层
Amontoffloors++;
}
}
//层数乘以高度
返回楼层数*高度;
}

干杯

通过去掉height参数(“所有对象的高度相同”),您可以在思想上对此进行简化。你能举一个例子说明你贪婪的解决方案吗?为什么它不能给出正确的答案?他们是如何相互支持的?他们形成一个三角形,每个人站在下面两个相邻的人的两个肩膀上吗?我很确定这是NP完全的。在可变高度的情况下,我发现了从子集和到这个问题的简单简化。我很确定对于固定高度的情况也可以找到类似的论点。事实上,我开始认为固定高度的情况可能比可变高度的情况容易得多。我有一个想法,通过总是添加最大化整个堆栈承载能力的人来实现。嗯。如果你贪婪地加上承载能力最大化器,那就不太管用了,但他下面最多只能有一个人。这至少减少了搜索树的有效深度,但我还没有弄清楚它是否可以用于生成多项式时间算法。
int amountOfMens    = n;
float weight        = w;
float strength      = s;
float height        = h;
int []mensInEachFloor;


public void MyAlg()
{
    mensInEachFloor = new int[ amountOfMens ]; // the max height that we can achieve is the max amount of mens.

    for(int i=0; i < mensInEachFloor.Length; i++ )
    {
        // we put one men on each floor, just to check if the highest heigth is achivable 
        mensInEachFloor[i] = 1;
    }

    // now we start to use our algorithm
    // for each floor:
    for(int i = 0; i < mensInEachFloor.Length; i++ )
    {
        // for each floor we will work on it until supports its designed weight 
        bool floorOk = false;

        while(! floorOk)
        {
            // we check if the weigth of all the higher floors can be supported by this level
            float weightToBeSupported       = TotalWeightOfHigherFloors(i+1);
            float weightThatCanBeSupported  = WeightHandledByFloor(i);

            if( weightToBeSupported > weightThatCanBeSupported )
            {
                // Remove one men from the top 
                RemoveOneManFromHighestFloor();
                // add one men to this floor to help with the weight
                AddOneManToFloor(i);
            }
            else
            {
                // we are ok on this floor :)
                floorOk = true;
            }
        }
    }

    Debug.Log("The total heigth of the tower is : " + GetTowerHeight() );
}

private float TotalWeightOfHigherFloors(int startingFloor)
{
    float totalWeight = 0;
    for(int i= startingFloor; i< mensInEachFloor.Length; i++ )
    {
        totalWeight += mensInEachFloor[i] * weight;
    }

    return totalWeight;
}

private float WeightHandledByFloor(int floor)
{
    return mensInEachFloor[floor] * strength;   
}

private void RemoveOneManFromHighestFloor()
{
    // we start to see from the top..
    for(int i = mensInEachFloor.Length - 1 ; i >= 0; i-- )
    {
        // if on this floor are one or more mens..
        if(mensInEachFloor[i] != 0)
        {
            // we remove from the floor
            mensInEachFloor[i] = mensInEachFloor[i] - 1;
            // and we are done
            break;
        }
    }
}

private void AddOneManToFloor(int floor)
{
    // Add one man to the selected floor
    mensInEachFloor[floor] = mensInEachFloor[floor] + 1;
}

private float GetTowerHeight()
{
    // We will count the number of floors with mens on it
    float amountOfFloors = 0;
    for(int i= 0; i< mensInEachFloor.Length; i++ )
    {
        // If there are more than zero mens
        if( mensInEachFloor[i] > 0 )
        {
            // it means that it is a valid floor
            amountOfFloors++;
        }
    }

    // number of floors times height
    return amountOfFloors * height;

}