在这里插入图片描述
UVA10003
这是一道区间动态规划
定义:$dp[i][j]$为第$i$个切割点到第$j$个切割点之间的木条的最小切割费用,$Point[i]$为第$i$个切割点的位置。
初始化

因为相邻切割点之间没有切割点,不需要切割。

在头和尾也添加切割点,方便枚举
转移方程

$i$到$j$要切成$ik$和$kj$,需要花费$ij$长度的代价,即$Point[j]-Point[i]$。
AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[51][1001], L, n, Point[52];
bool Input() {
cin >> L;
if (!L) {
return false;
}
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> Point[i];
}
return true;
}
int DP() {

Point[n + 1] = L;
dp[0][1] = 0;

for (int i = 1; i <= n; ++i) {
dp[i][i + 1] = 0;
}
//枚举区间长度
for (int NumberOfPoint = 2; NumberOfPoint <= n + 1; NumberOfPoint++) {
//枚举起点
for (int i = 0; i + NumberOfPoint <= n + 1; i++) {
int
&&j = i + NumberOfPoint,
&&minn = 0xfffffff;
//枚举中转点
for (int k = i + 1; k < j; k++) {
minn = min(minn, dp[i][k] + dp[k][j]);
}
dp[i][j] = minn + Point[j] - Point[i];
}
}

return dp[0][n + 1];
}
int main() {
ios::sync_with_stdio(false);
while (Input()) {
cout << "The minimum cutting is " << DP() << "." << endl;
}
return 0;
}