C# 查找X天数的最便宜价格

C# 查找X天数的最便宜价格,c#,.net,algorithm,C#,.net,Algorithm,我有一个关于算法的技术挑战 假设我有一张天数和价格的清单: List<ReservationPrice> prices = new List<ReservationPrice>(); prices.Add(new ReservationPrice { NumberOfDays = 1, Price = 1000 }); prices.Add(new ReservationPrice { NumberOfDays = 2, P

我有一个关于算法的技术挑战

假设我有一张天数和价格的清单:

        List<ReservationPrice> prices = new List<ReservationPrice>();
        prices.Add(new ReservationPrice { NumberOfDays = 1, Price = 1000 });
        prices.Add(new ReservationPrice { NumberOfDays = 2, Price = 1200 });
        prices.Add(new ReservationPrice { NumberOfDays = 3, Price = 2500 });
        prices.Add(new ReservationPrice { NumberOfDays = 4, Price = 3100 });
        prices.Add(new ReservationPrice { NumberOfDays = 7, Price = 4000 });
List prices=新列表();
添加(新预订价格{NumberOfDays=1,价格=1000});
添加(新预订价格{NumberOfDays=2,价格=1200});
添加(新预订价格{NumberOfDays=3,价格=2500});
添加(新预订价格{NumberOfDays=4,价格=3100});
添加(新预订价格{NumberOfDays=7,价格=4000});
我现在想做的是:

根据天数从列表中给我一个最优惠的价格

因此,如果要求3天,列表中的最佳价格是儿童一(1000)和儿童二(1200),但当然有不同的组合,你必须首先尝试。从这个列表中找到最佳价格的算法是什么样子的


谢谢大家!

上面链接的wiki页面说这是一个np完全问题,所以我想没有好办法解决它。 但是,如果您想强制执行,我建议您首先过滤掉“无用”字段

在您的示例中,通过一些简单的检查,您可以过滤掉3和4,因为它们总是可以被1+2和2+2覆盖。(你也可以用蛮力来做到这一点)

那么,你应该只剩下3个组合可供选择,如果你为一家租赁公司或酒店制作节目,这应该不会太糟糕

(如果您想查看30天内的最佳价格,则最多只需30 x 15 x 4次操作,这对于计算机计算来说根本没有那么大。)

Hi Wizardofods:

我正试图学习如何解决这个问题,作为0-1背包,我有点困惑

(你可以简单地“播种”你的“0-1 背包“一天”的数量为 您希望找到的最大值,为 很多“两天”,三分之一的时间 “三天”等)

我是否应该理解,如果我们想在7天内找到解决方案,那么我们认为:

7 x 1天0/1

3倍2天0/1

2x 3天0/1

1x 4天0/1

我想,我真的不明白这是什么/为什么

“一天”、“一半”、“三天”的数量

它和这个类似

以下是伪代码优先的算法:

Let S[i] = minimum sum obtainable for days = i, initialized to infinite at first
S[0] = 0
for (int i = 0; i < prices.Count; ++i)
{
    for (int j = MAX_DAYS; j >= prices[i].days; --j)
        S[j] = min(S[j], S[j - prices[i].days] + prices[i].price);
}

虽然这基本上是背包问题,但您可以做一些简单的分析来过滤出错误的决策(在您的示例中,是3天和4天的预订包)

首先,我会根据天数和每天的平均价格对列表进行排序。在你的例子中,这将产生

Days Average ---- ------- 1 1000 2 600 3 833 4 775 7 571 平均天数 ---- ------- 1 1000 2 600 3 833 4 775 7 571 然后,我将过滤掉在遍历此列表时增加的所有值。一个简单的假设是,如果一天的平均住院时间较短,那么通过使用X次较短住院时间的总和,一天的平均住院时间会增加,因此可以获得更好的住院率(显然不是所有时间都是正确的——将1天住院率设为1301,3天住院率会变好,但4天住院率仍然很差——尽管在您的示例中确实有效)。更详细的分析将此转化为背包问题

Days Average ---- ------- 1 1000 2 600 3 833 removed 4 775 removed 7 571 平均天数 ---- ------- 1 1000 2 600 3833已删除 4775已删除 7 571
现在,当建立预订时,通过从所需的天数中减去最大可能的预订,按天数递减排序,直到您完成预订。所以11天的预订是7天和2天;10天可能是7天、2天和1天。

@user227353:对我来说,这相当于一个0-1背包,它有一个非常有效的已知DP解决方案。没有必要在这里发力,也不认为这是NP完全背包。我很确定这相当于一个“0-1背包”:因此有一个已知的DP(动态规划)解决方案,适用于大多数输入(以防它不适用于OP的数据[因为他们将使用巨大的数字,使得精确的DP算法不适用,这是非常不可能的]然后你可以找到一个近似值,你可以证明这个近似值最多是最佳答案的“x”。完全误解了你在第一次阅读时提出的问题…(随后:喝了一些咖啡,更好地理解了!)忽略我的答案,以防它还没有消失。@danielovich:AFAICT这可以精确地表述为“0-1背包”,这比一般的背包更容易解决(你可以简单地“播种”你的“0-1背包”,用你想要找到的最多的“一天”,一半的“两天”,三分之一的“三天”,等等)。实际上,0-1背包是一个非常优雅的“DP”解决方案,速度非常快。 Days Average ---- ------- 1 1000 2 600 3 833 removed 4 775 removed 7 571