矩阵链乘的问题,好像很多算法书上讲DP都是开始就将矩阵链乘。这个题不是要求最小的运算量,而是求最优的方案是什么,难就难在了递归的输出,如何记录路径,如何输出。
我也是参看了别人的代码。递归输出。不过这个转移方程还是蛮好找的。dp[i][j] = min ( dp[i][k], dp[k + 1][j], p[i - 1]p[k]p[j] ).
// File Name: UVa348.cpp
// Author: Toy
// Created Time: 2013年04月15日 星期一 19时03分31秒
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cctype>
#include <cmath>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <utility>
#include <bitset>
#define L(x) x << 1
#define R(x) x << 1 | 1
using namespace std;
int num, path[15][15], p[15], dp[15][15], Case, tmp;
void output ( int i, int j ) {
if ( i == j ) printf ( "A%d", i );
else {
printf ( "(" );
output ( i, path[i][j] );
printf ( " x " );
output ( path[i][j] + 1, j );
printf ( ")" );
}
}
void DP ( ) {
for ( int d = 2; d <= num; ++d ) {
for ( int i = 1, j = d; j <= num; ++i, ++j ) {
dp[i][j] = 10000000000;
for ( int k = i; k < j; ++k ) {
tmp = dp[i][k] + dp[k + 1][j] + p[i - 1] * p[j] * p[k];
if ( dp[i][j] > tmp ) dp[i][j] = tmp, path[i][j] = k;
}
}
}
}
int main ( ) {
Case = 0;
while ( scanf ( "%d", &num ) != EOF && num ) {
for ( int i = 1; i <= num; ++i )
scanf ( "%d%d", &p[i - 1], &p[i] );
memset ( dp, 0, sizeof ( dp ) );
memset ( path, 0, sizeof ( path ) );
DP ( );
printf ( "Case %d: ", ++Case );
output ( 1, num );
printf ( "\n" );
}
return 0;
}
本文详细探讨了矩阵链乘问题中如何使用动态规划算法找到最优的运算方案,包括转移方程的建立与递归输出路径的过程。通过实例代码展示了算法的具体实现,包括初始化状态、状态转移方程、输出最优路径的方法。
1525

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



