- // [解题方法]
- // 记忆化搜索(递归,子问题的结果用备忘录存起来,避免重复求解)
- // 设棍子长度n,输入的c[i]是棍子上的坐标
- // dp[x][y](即dfs(x,y))表示砍c[x]到c[y]段的最小花费
- // 每次砍c[x]~c[y]段的时候枚举砍的位置i
- // 状态转移:dp[x][y] = min(dp[x][i] + dp[i][y] + c[y]-c[x])(x<=i<=y)
- // 注:-1表示无穷大
- #include <iostream>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <algorithm>
- using namespace std;
- #define LL long long
- #define M 55
- #define inf 0x3fffffff
- int dp[M][M], c[M];
- int dfs (int x, int y)
- {
- if (dp[x][y] > -1)
- return dp[x][y];
- int tp = -1, i;
- for (i = x+1; i < y; i++)
- {
- int tmp = dfs(x, i) + dfs(i, y) + c[y] - c[x];
- if (tp < 0 || tmp < tp) tp = tmp;
- }
- return (dp[x][y] = tp);
- }
- int main()
- {
- int n, m, i;
- while (cin >> n, n)
- {
- cin >> m;
- c[0] = 0;
- for (i = 1; i <= m; i++) {
- cin >> c[i];
- }
- c[m+1] = n;
- memset (dp, -1, sizeof(dp));
- for (i = 0; i <= m; i++)
- dp[i][i+1] = 0;
- cout << "The minimum cutting is " << dfs(0, m+1) << "." << endl;
- }
- return 0;
- }