动态编程算法?

时间:2010-04-22 15:24:58

标签: algorithm dynamic-programming

我对如何最好地设计此算法感到困惑。一艘船有x个海盗,其中j th 海盗的年龄是 j ,j th 海盗的重量是w Ĵ。我正在考虑一种动态编程算法,它将找到最老的海盗,其体重在所有海盗的二十五到七十五百分位之间。但是对于如何继续我一无所知。

4 个答案:

答案 0 :(得分:3)

天真的解决方案(可能不是最有效的,但是第一个突然出现在我脑海中,并且很简单):

按重量对盗版列表进行排序。然后循环遍历列表的中间50%,搜索具有最大年龄的盗版。

假设您使用有效的排序算法,运行时将是n log(n)+ n / 2 - >为O(n 的log(n))。

答案 1 :(得分:2)

可能有O(n)解决方案。

必要条件是权重必须被视为整数并受某个上限的约束。在现实世界中,这是真的,因为在描述某人的体重时,我们从未真正需要小数点后的一位数。你的体重不能超过10000磅。

然后你可以使用bucket sort(这是O(n))来找出有趣百分位数的限制在哪里,然后简单地寻找那里最老的海盗(也是O(n))

修改,澄清:

权重本身不能是整数,但只要精度有限(到固定和合理的小数位数),你总是可以将它们全部相乘,使它们成为整数。例如,表示权重为167.8为1678。

编辑,解释存储桶排序:

如果您需要详细说明,请阅读维基百科文章。我将在这里为你的案例做一个例子。假设有一个名为pirates的列表。然后我们可以将它们分类为新列表sortedPirates。正如我之前所解释的那样,要求它起作用的是:1)盗版权重是整数的(或者可以表示为这样)和2)不同权重的数量(或权重的表示)受上限的约束。我假设整体重量和10000磅的上限:

// Put the pirates into buckets (each bucket is a linked list, or null if empty)
var upperWeightBound = 10000;
var buckets = new LinkedList<Pirate>[upperWeightBound];
foreach (var pirate in pirates)
{
    if (buckets[pirate.weight] == null)
        buckets[pirate.weight] = new LinkedList<Pirate>();
    buckets[pirate.weight].AddLast(pirate);
}

// Extract the bucketed pirates into a single, now sorted, linked list
var sortedPirates = new LinkedList<Pirate>();
foreach (var bucket in buckets)
    if (bucket != null)
        foreach (var pirate in bucket)
            sortedPirates.AddLast(pirate);

答案 2 :(得分:1)

在我的头顶,我按重量对数据进行排序,然后选择最小权重作为j = 1/4 * x的盗版,最大允许权重为j = 3/4 * x时的海盗。然后我会遍历一组海盗,检查他们的体重是否大于最小值或大于最大值。如果此检查成功,则该盗版者可能是候选人。如果没有当前候选者,则选择此盗版者作为当前候选人。如果有当前候选人,则只有当他的年龄大于当前候选人时才选择此盗版作为新的当前候选人。

对候选人进行排序可以在O(nlogn)中完成。选择具有合适数据结构的上/下重量是O(1)操作。找到最老的合格候选人是O(n)。所以总算法是O(nlogn)。

使用Snippet Compiler for C#:

public class Pirate
{
    public int ID { get; set; }
    public int Age { get; set; }
    public int Weight { get; set; }
}


var pirates = new List<Pirate>();
int max = 20;

Random rng = new Random();
for (int j = 0; j < max; ++j)
{
    var pirate = new Pirate();
    pirate.ID = j;
    pirate.Age = rng.Next(45) + 15;
    pirate.Weight = rng.Next(100) + 100;
    pirates.Add(pirate);
}

pirates.Sort( (a,b) => a.Weight.CompareTo( b.Weight ) );

int lowWeight = pirates[max/4].Weight;
int highWeight = pirates[max*3/4].Weight;

Pirate chosen = null;
foreach (var pirate in pirates)
{
    if (pirate.Weight >= lowWeight && pirate.Weight <= highWeight)
    {
        if (chosen == null || pirate.Age > chosen.Age)
        {
            chosen = pirate;
        }
    }
}

Console.WriteLine( "Chosen {0}: Age {1}, Height {2}", chosen.ID, chosen.Age, chosen.Weight );

答案 3 :(得分:1)

你可以在线性时间内非常有效地解决它。

1)使用线性时间i阶统计量“选择算法”来找到权重为25百分位的海盗。

2)再次使用相同的算法来查找权重为75%的盗版。

3)过滤掉属于这两个边界的海盗 - 再次以线性时间。

4)对于合格的海盗,按年龄标准计算MAX。 - 再次在线性时间。