【发布时间】:2015-03-24 17:48:44
【问题描述】:
假设有 150 张优惠券要消费。
在每次迭代中有 3 种方法可以使用它们 - 一次 15 次,一次 1 次或每次正好一半。
很明显,一张优惠券只能全部消费。
我们需要找出优惠券运行到 0 的最短路径(迭代次数)。
暴力破解是唯一的出路吗?
或者我们有解决这种情况的算法吗?
【问题讨论】:
标签: algorithm dynamic-programming brute-force
假设有 150 张优惠券要消费。
在每次迭代中有 3 种方法可以使用它们 - 一次 15 次,一次 1 次或每次正好一半。
很明显,一张优惠券只能全部消费。
我们需要找出优惠券运行到 0 的最短路径(迭代次数)。
暴力破解是唯一的出路吗?
或者我们有解决这种情况的算法吗?
【问题讨论】:
标签: algorithm dynamic-programming brute-force
这可以通过以下递归公式在Dynamic Programming (DP) 中解决:
D(x) = INFINITY x < 0
D(0) = 0
D(x) = min{ D(x-1), D(x-15), D(x/2) } + 1
在自下而上的 DP 中,它将类似于:(伪代码)
D = new int[151]
D[0] = 0
for (int i = 1; i <151; i++) {
best = min(D[i-1], D[i/2]) //add floor or ceil according to definition of problem to i/2
if (i >= 15):
best = min(best, D[i-15])
D[i] = best + 1
}
return D[150]
【讨论】:
D(x-k1), D(x-k2) 会导致指数行为。其中最著名的是斐波那契数列,k1=1, k2=2。你有 k1=1,k2=15 - 这将提供更好的行为 - 但仍然是指数级的,甚至没有考虑 D(x/2)。