确定分发这些优惠券的最佳方式的算法是什么?

Blo*_*ard 7 algorithm

这是我的问题.想象一下,我正在购买3种不同的商品,而且我有多达5张优惠券.优惠券是可以互换的,但在用于不同物品时价值不同.

这是矩阵,它给出了在不同项目上花费不同数量的优惠券的结果:

coupons:    1         2         3         4         5
item 1      $10 off   $15 off
item 2                $5 off    $15 off   $25 off   $35 off
item 3      $2 off
Run Code Online (Sandbox Code Playgroud)

我已手动制定了此示例的最佳操作:

  • 如果我有1张优惠券,则第1件可获得10美元优惠券
  • 如果我有2张优惠券,则第1项可获得15美元优惠券
  • 如果我有3张优惠券,则第1项获得2,第3项获得1,仅需17美元
  • 如果我有4张优惠券,然后要么:
    • 项目1获得1,项目2获得3,总共25美元,或
    • 第2项获得全部4折25美元.
  • 如果我有5张优惠券,则第2项将获得全部5张优惠券,价格为35美元.

但是,我需要开发一种通用算法来处理不同的矩阵和任意数量的项目和优惠券.

我怀疑我需要遍历每个可能的组合,以找到n优惠券的最佳价格.这里有没有人有任何想法?

Fry*_*Guy 4

这似乎是动态规划的一个很好的候选者:

//int[,] discountTable = new int[NumItems][NumCoupons+1]

// bestDiscount[i][c] means the best discount if you can spend c coupons on items 0..i
int[,] bestDiscount = new int[NumItems][NumCoupons+1];

// the best discount for a set of one item is just use the all of the coupons on it
for (int c=1; c<=MaxNumCoupons; c++)
    bestDiscount[0, c] = discountTable[0, c];

// the best discount for [i, c] is spending x coupons on items 0..i-1, and c-x coupons on item i
for (int i=1; i<NumItems; i++)
    for (int c=1; c<=NumCoupons; c++)
        for (int x=0; x<c; x++)
            bestDiscount[i, c] = Math.Max(bestDiscount[i, c], bestDiscount[i-1, x] + discountTable[i, c-x]);
Run Code Online (Sandbox Code Playgroud)

最后,最佳折扣将是 bestDiscount[NumItems][x] 的最高值。要重建树,请按照图表向后进行:

编辑添加算法:

//int couponsLeft;

for (int i=NumItems-1; i>=0; i++)
{
    int bestSpend = 0;
    for (int c=1; c<=couponsLeft; c++)
        if (bestDiscount[i, couponsLeft - c] > bestDiscount[i, couponsLeft - bestSpend])
            bestSpend = c;

    if (i == NumItems - 1)
        Console.WriteLine("Had {0} coupons left over", bestSpend);
    else
        Console.WriteLine("Spent {0} coupons on item {1}", bestSpend, i+1);

    couponsLeft -= bestSpend;
}
Console.WriteLine("Spent {0} coupons on item 0", couponsLeft);
Run Code Online (Sandbox Code Playgroud)

将图形存储在数据结构中也是一个好方法,但这就是我想到的方法。