Cutting Sticks |
It is easy to notice that different selections in the order of cutting can led to different prices. For example, consider a stick of length 10 meters that has to be cut at 2, 4 and 7 meters from one end. There are several choices. One can be cutting first at 2, then at 4, then at 7. This leads to a price of 10 + 8 + 6 = 24 because the first stick was of 10 meters, the resulting of 8 and the last one of 6. Another choice could be cutting at 4, then at 2, then at 7. This would lead to a price of 10 + 4 + 6 = 20, which is a better price.
Your boss trusts your computer abilities to find out the minimum cost for cutting a given stick.
The next line consists of n positive numbers ci ( 0 < ci < l) representing the places where the cuts have to be done, given in strictly increasing order.
An input case with l = 0 will represent the end of the input.
100 3 25 50 75 10 4 4 5 7 8 0
The minimum cutting is 200. The minimum cutting is 22.题意:给定一段len长的木棍,有n个切割点,每个切割点切掉的花费是当前切割点所在木棍的长度,求最少的花费。
思路:这题我是把每个木棍分成已经切割好的状态,在从切割好进行复原,复原过程中用区间dp的方法记录花费。
状态转移方程为dp[i][j] = min{dp[i][k] + dp[k + 1][j] + he(当前要复原的长度)}。
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int len, n, strick[55], i, j, k, l, sb, sbb, dp[55][55]; int min(int a, int b) { return a < b ? a : b; } int main() { while (~scanf("%d", &len) && len) { sbb = 0; memset(dp, 0, sizeof(dp)); scanf("%d", &n); for (i = 1; i <= n; i ++) { scanf("%d", &sb); strick[i] = sb - sbb; sbb = sb; } strick[++ n] = len - sb; for (l = 1; l < n; l ++) { for (i = 1; i <= n - l; i ++) { j = i + l; int sb = 999999999; int he = 0; for (k = i; k <= j; k ++) he += strick[k]; for (k = i; k < j; k ++) { sb = min(dp[i][k] + dp[k + 1][j] + he, sb); } dp[i][j] = sb; } } printf("The minimum cutting is %d.\n", dp[1][n]); } return 0; }