如果您从几何角度考虑它,请考虑一个图表,该图表显示总价格(纵坐标)作为购买的商品总数(横坐标)的函数。情节开始于(0, 0)
(购买零成本为零)。1.65
首先我们得到一条斜率和水平宽度的直线段5000
。然后从它的终点出现一个新的坡度1.6
和宽度段10000
。总地块是连续的、分段的直线,但在单价变化的地方有弯曲。
然后要解决您的问题,找到与方程线的交点y == 1.57 * x
,即从 开始(0, 0)
并具有斜率的线1.57
。对于每个段(您知道其两个端点),检查该段是否满足y == 1.57 * x
,如果满足,则有您的解决方案。
如果您的price
数组中的数字正在减少,则最多可以有一个解决方案(假设它1.57
严格小于第一个价格price[0]
),该图表示一个凹函数。
编辑:我试图用 C# 编写这个几何图形。我没有添加price
所有正面和减少的支票,而且quantity
都是正面的。你必须检查一下。这是我的代码:
decimal[] price = { 1.65m, 1.6m, 1.55m, 1.4m, 1.3m, };
long[] quantity = { 5000, 10000, 12000, 20000, 50000, };
decimal desiredAverage = 1.57m;
int length = price.Length;
if (length != quantity.Length)
throw new InvalidOperationException();
var abscissaValues = new long[length + 1];
var ordinateValues = new decimal[length + 1];
for (int i = 1; i <= length; ++i)
{
for (int j = 0; j < i; ++j)
{
abscissaValues[i] += quantity[j];
ordinateValues[i] += price[j] * quantity[j];
}
} // calculation of plot complete
int segmentNumber = Enumerable.Range(1, length).FirstOrDefault(i => ordinateValues[i] / abscissaValues[i] <= desiredAverage);
if (segmentNumber > 1)
{
decimal x = (ordinateValues[segmentNumber - 1] * abscissaValues[segmentNumber] - abscissaValues[segmentNumber - 1] * ordinateValues[segmentNumber])
/ (desiredAverage * (abscissaValues[segmentNumber] - abscissaValues[segmentNumber - 1]) - (ordinateValues[segmentNumber] - ordinateValues[segmentNumber - 1]));
Console.WriteLine("Found solution x == " + x);
}
else
{
Console.WriteLine("No solution");
}
不知道有没有人能写得更漂亮一些,不过好像还行。输出是:
找到解决方案 x == 29705.882352941176470588235294