题目来源:Acwing,算法竞赛进阶指南
这题一看,让我不经意想到了矩阵链相乘,似乎是两个非常相似的问题。
①状态转移方程
f[i, j] = min{f[i, k] + f[k + 1, j] + m[i, k] * m[k + 1, j]}
边界条件:只有一袋,不用搬,为0
填表方式:对角线
②设计表格
存放:合并从i到j最小体力 | j+ |
i+ |
③结果
取结果f[1, n]
④核心代码
for(int i = 1; i <= N; i++)
f[i][i] = 0; //初始化边界条件
for(int m = 2; m <= N; m++)
for(int j = m, i = 1; i <= N && j <= N; j++ ,i++)
for(int k = i; k < j; k++)
{
int tmp = f[i][k] + f[k + 1][j] + (M[k] - M[i - 1]) + (M[j] - M[k]);
cout << tmp << ' ';
f[i][j] = (f[i][j] == 0) || f[i][j] > tmp ? tmp : f[i][j];
}
全代码:
#include <iostream>
using namespace std;
int f[305][305];
int m[305];
int main()
{
int N;
int M[305];
cin >> N;
for(int i = 1; i <= N; i++)
cin >> m[i];
m[0] = M[0] = 0; //使用M数组辅助计算总质量
for(int i = 1; i <= N; i++)
M[i] = M[i - 1] + m[i];
for(int i = 1; i <= N; i++)
f[i][i] = 0; //初始化边界条件
for(int m = 2; m <= N; m++)
for(int j = m, i = 1; i <= N && j <= N; j++ ,i++)
for(int k = i; k < j; k++)
{
int tmp = f[i][k] + f[k + 1][j] + (M[k] - M[i - 1]) + (M[j] - M[k]);
cout << tmp << ' ';
f[i][j] = (f[i][j] == 0) || f[i][j] > tmp ? tmp : f[i][j];
}
cout << endl;
for(int i = 0; i <= N; i++, cout << endl)
for(int j = 0; j <= N; j++)
cout << f[i][j] <<'\t';
cout << f[1][N] ;
}
通过了acwing online judge。