题目描述
出于某些方面的需求,我们要把一块N×M的木板切成一个个1×1的小方块。
对于一块木板,我们只能从某条横线或者某条竖线(要在方格线上),而且这木板是不均匀的,从不同的线切割下去要花不同的代价。而且,对于一块木板,切割一次以后就被分割成两块,而且不能把这两块木板拼在一起然后一刀切成四块,只能两块分别再进行一次切割。
现在,给出从不同的线切割所要花的代价,求把整块木板分割成1×1块小方块所需要耗费的最小代价。
输入格式
输入文件第一行包括N和M,表示长N宽M的矩阵。
第二行包括N-1个非负整数,分别表示沿着N-1条横线切割的代价。
第二行包括M-1个非负整数,分别表示沿着M-1条竖线切割的代价。
代码
#include <fstream>
using namespace std;
ifstream fin("cut.in");
ofstream fout("cut.out");
const int N = 2001, M = 2001;
int ans[M][N]; //1维m2维n
int hang[N], lie[M];
int quick_sort(int a[], int low, int high) {
int i = low, j = high, temp = a[j];
if (i >= j) return 0;
while (i < j) {
while (i < j && a[i] >= temp) i++;
if (i < j) a[j--] = a[i];
while (i < j && a[j] <= temp) j--;
if (i < j) a[i++] = a[j];
}
a[i] = temp;
quick_sort(a, i + 1, high);
quick_sort(a, low, i - 1);
return 0;
}
int dp(int a[M][N], int n, int m) {
int i, j;
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++) {
a[i][j] = min(a[i - 1][j] + lie[i] * (j + 1), a[i][j - 1] + hang[j] * (i + 1));
}
return a[m][n];
}
int work1(int a[M][N], int n, int m) {
int i = 1;
int s = 0;
quick_sort(hang, 1, n);
quick_sort(lie, 1, m);
for (i = 1; i <= m; i++) {
s += lie[i];
a[i][0] = s;
}
s = 0;
for (i = 1; i <= n; i++) {
s += hang[i];
a[0][i] = s;
}
return 0;
}
int main() {
int n, m;
int i, j;
fin >> n >> m;
n--;
m--;
for (i = 1; i <= n; i++) {
fin >> hang[i];
}
for (i = 1; i <= m; i++) {
fin >> lie[i];
}
work1(ans, n, m);
fout << dp(ans, n, m);
return 0;
}
这篇博客探讨了一种使用动态规划方法解决如何将一块大小为N×M的不均匀木板分割成1×1小方块的问题。每次切割会带来不同代价,并且木板分割后不可再合并。内容提供了输入格式说明,包括木板尺寸和各切割线的代价,以及问题的解决方案——找到最小切割总代价。
(附C语言实现)&spm=1001.2101.3001.5002&articleId=4810208&d=1&t=3&u=c647eed4ed804e68b6dfc56e47d34606)
5438

被折叠的 条评论
为什么被折叠?



