考虑d(i,j)表示切割点i到j这段距离的最小花费,于是d(i,j)=min(d(i,k)+d(k,j))+a[j]-a[i] ,其中j<k<i,边界条件d(i,i)=d(i,i+1)=0,最终求d(0,n+1),复杂度o(n^3),可采用记忆化搜索。
/*----UVa10003 Cutting Sticks 设d(i,j)为切割木棍(i,j)的最小费用,则d(i,j)=a[j]-a[i]+min{d(i,k)+d(k,j)} i<k<=j;最终求d(0,n+1) 为了方便,可以采用记忆化搜索 */ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<algorithm> #include<string.h> using namespace std; #define INF 0x3f3f3f3f const int maxn =50+5; int n, L,curr; int dp[maxn][maxn],a[maxn]; int dfs(int i, int j){ if (j - i <= 1) return 0; int &ans = dp[i][j]; if (ans >= 0) return ans; ans = INF; for (int k = i + 1; k < j; k++){ ans = min(ans, dfs(i, k) + dfs(k, j) + a[j] - a[i]); } return ans; } int main(){ while (scanf("%d", &L)&&L){ scanf("%d", &n); a[0] = 0, a[n + 1] = L; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); memset(dp, -1, sizeof(dp)); printf("The minimum cutting is %d. ", dfs(0, n + 1)); } return 0; }