Algorithm 消费的最小路径

Algorithm 消费的最小路径,algorithm,dynamic-programming,brute-force,Algorithm,Dynamic Programming,Brute Force,假设要消费150张优惠券。 在每次迭代中有3种方法使用它们-每次15个,每次1个,或者每次正好一半。 显然,优惠券只能全部消费。 我们需要找出最短路径(#迭代次数),使优惠券运行到0。 暴力是唯一的出路吗? 或者我们有解决这种情况的算法。这可以通过以下递归公式来解决: D(x) = INFINITY x < 0 D(0) = 0 D(x) = min{ D(x-1), D(x-15), D(x/2) } + 1 D(x)=无穷大x

假设要消费150张优惠券。
在每次迭代中有3种方法使用它们-每次15个,每次1个,或者每次正好一半。
显然,优惠券只能全部消费。
我们需要找出最短路径(#迭代次数),使优惠券运行到0。
暴力是唯一的出路吗?
或者我们有解决这种情况的算法。

这可以通过以下递归公式来解决:

D(x) = INFINITY x < 0
D(0) = 0
D(x) = min{ D(x-1), D(x-15), D(x/2) } + 1
D(x)=无穷大x<0
D(0)=0
D(x)=min{D(x-1),D(x-15),D(x/2)}+1
在自下而上的DP中,它类似于:(伪代码)

D=newint[151]
D[0]=0
对于(int i=1;i=15):
最佳=最小值(最佳,D[i-15])
D[i]=最佳+1
}
返回D[150]

但是Dp会是最有效的解决方案吗?考虑到子解决方案的重叠不会那么频繁。蛮力递归难道不具有可比性吗?@IUnknown Long story short-不,至少对于#优惠券的大值来说是如此。请注意,对任意两个常数k1、k2调用
D(x-k1)、D(x-k2)
都会导致指数行为。其中最著名的是fibonacci序列,k1=1,k2=2。k1=1,k2=15——这将提供更好的行为——但仍然是指数型的,甚至不考虑D(x/2)。
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]