如何解决极限最大值的杆切削问题。削减允许?

时间:2017-05-24 05:11:41

标签: algorithm

我知道如何使用动态编程解决杆切割问题。 但是当我们限制允许的最大切割次数时,动态编程无法给出正确的答案。即使我想不出问题的递归解决方案。救命。

这是问题,
确定通过切割杆和销售件可获得的最大收入 给定一根长度为N的杆,以及长度为i的杆的价格表P(i)。你可以在给定的杆上进行不超过K次切割。

例如:
N = 10
K = 3
| p(1)= 1 | p(2)= 5 | p(3)= 8 | p(4)= 9 | p(5)= 10 | p(6)= 22 | p(7)= 17 | p(8)= 20 | p(9)= 24 | p(10)= 30 |

通过将杆切割成长度为6和4的2个(切割总数= 1,小于K = 3),最大可获得收益为31。

1 个答案:

答案 0 :(得分:4)

我们可以通过添加第二维来扩展动态编程解决方案,这是迄今为止的切割数量。

D[n][k],使用精确n剪辑的k长度的杆的最大收入可以定义如下:

D[n][k] = max(price[i] + D[n-i-1][k-1]) for all i in {1, 2, ..., n}

由于我们希望最多 K削减,而不是完全,因此最高收入将为:

maxRevenue(N) = max(D[N][k]) for all k in {1, 2, ..., k}

这将是O(N²K),因为我们需要遍历所有k(与经典问题的O(N²)相比)。

(Java)代码:

int[] price = {1, 5, 8, 9, 10, 22, 17, 20, 24, 30};
int N = price.length;
int K = 3;
int[][] D = new int[N+1][K+1];

for (int n = 1; n <= N; n++)
    D[n][0] = price[n-1];

for (int k = 1; k <= K; k++)
for (int n = 0; n <= N; n++)
for (int i = 0; i <= n-1; i++)
    D[n][k] = Math.max(D[n][k], price[i] + D[n-i-1][k-1]);

int best = 0;
for (int k = 0; k <= K; k++)
    best = Math.max(best, D[N][k]);

System.out.println(best);

Live demo