https://vjudge.net/problem/UVA-10003
题意:
有一根长度为L的棍子,还有n个切割点的位置。你的任务是在这些切割点的位置处把棍子切成n+1部分,使得总切割费用最小。每次切割的费用等于被切割的木棍长度。例如,L=10,切割点为2,4,7。如果按照2,4,7的顺序,费用为10+8+6=4,如果按照4,2,7的顺序,费用为10+4+6=0.
思路:
这道题目和最优矩阵链乘是一样的,方法是按照区间大小递增的顺序递推,因为长区间的值依赖于短区间的值。
设d(i,j)为切割小木棍i~j的最优费用,则转移方程为d(i,j)=min{ d(i,j) , d(i,k)+d(k,j)+a[j]-a[i] }。
把切割点编号为1~n,左边界编号为0,右边界编号为n+1,则答案为d(0,n+1)。
#include<iostream> #include<algorithm> #include<cstring> #include<string> using namespace std; const int INF = 100000000; int length, n; int a[55]; int d[55][55]; int main() { //freopen("D:\txt.txt", "r", stdin); while (cin>>length && length) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); a[0] = 0; a[n + 1] = length; for (int i = 1; i <= n + 1; i++) { for (int j = 0; j +i <= n + 1; j++) { int r = i + j; if (i == 1) d[j][r] = 0; else { d[j][r] = INF; for (int k = j + 1; k < r; k++) d[j][r] = min(d[j][r], d[j][k] + d[k][r] + a[r] - a[j]); } } } printf("The minimum cutting is %d. ", d[0][n + 1]); } return 0; }