问题
设有一个长度为 L 的钢条,在钢条上标有 n 个位置点(p1,p2,…,pn)。现在需要按钢
条上标注的位置将钢条切割为 n+1 段,假定每次切割所需要的代价与所切割的钢条长
度成正比。请编写一个算法,能够确定一个切割方案,使切割的总代价最小。
思路
代码
#include <iostream>
#include <algorithm>
#define NUM 1000
using namespace std;
class MinPrice {
private:
int m[NUM][NUM] = {0};
int s[NUM][NUM] = {0};
int d[NUM] = {0};
public:
void minmoney(int n, int l) {
for (int i = 1; i <= n; i++) {
cin >> d[i];
}
d[n + 1] = l;
sort(d, d + n + 1);
for (int i = 1; i <= n; i++) {
m[i][i] = d[i + 1] - d[i - 1];
}
for (int i = 1; i <= n; i++) {
m[i][i - 1] = 0;
}
for (int r = 2; r <= n; r++) {
for (int i = 1; i <= n - r + 1; i++) {
int j = r + i - 1;
m[i][j] = m[i + 1][j] + d[j + 1] - d[i - 1];
s[i][j] = i;
for (int k = i + 1; k <= j; k++) {
int t = m[i][k - 1] + m[k + 1][j] + d[j + 1] - d[i - 1];
if (t < m[i][j]) {
m[i][j] = t;
s[i][j] = k;
}
}
}
}
}
void prints(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << s[i][j] << ' ';
}
cout << endl;
}
cout << endl;
}
void printm(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << m[i][j] << ' ';
}
cout << endl;
}
cout << endl;
}
void trackback(int i, int j) {
if (i > j)
return ;
if (i == j) {
cout << i << endl;
return;
}
cout << s[i][j] << endl;
trackback(i, s[i][j] - 1);
trackback(s[i][j] + 1, j);
}
void show(int n) {
cout << m[1][n];
}
};
int main() {
MinPrice test;
int l, n;
cin >> l >> n;
test.minmoney(n, l);
test.show(n);
//test.printm(n);
//test.prints(n);
//test.trackback(1,n);
return 0;
}