设第i个矩阵为Ai,将矩阵连乘积AiAi+1…Aj记为A[i:j].
求A[1:n]最少计算次序.
采用完全加括号,即在不同位置将矩阵连乘分割,比较分割后最优,求出最优值。分割位置k(1<=k
#includeusing namespace std; //p存储 行列数,n=矩阵个数,m存矩阵最少乘次数(最优值),n存断开位置(最优解) void MatrixChain( int *p, int n, int m[][100], int s[][100] ) { for( int i = 1; i <= n; i++ ) { m[i][i] = 0; //对角线赋值为0,因为对角线表示单一矩阵,无最少乘次数 s[i][i] = 0; //同理,无断开位置 } for( int r = 2; r <= n; r++ ) { //r控制连乘时矩阵个数,r=2表示求两个矩阵最少乘 for( int i = 1; i <= n - r + 1; i++ ) { //i表示开始矩阵位置 int j = i + r - 1; //连乘矩阵结束位置 m[i][j] = m[i][i] + m[i + 1][j] + p[i - 1] * p[i] * p[j]; //断开位置在初始位置时的m //m[2][5]意思是 第2个矩阵到第5个矩阵(共4个矩阵)的连乘最少次数 //同理 s[2][5]意思是 第2个矩阵到第5个矩阵(共4个矩阵)的最少断点 s[i][j] = i; for( int k = i + 1; k < j; k++ ) { //断开位置 i<=k temp ) { m[i][j] = temp; s[i][j] = k; } } } } } void TraceBack( int i, int j, int s[][100] ) { if( i == j ) { return ; } TraceBack( i, s[i][j], s ); TraceBack( s[i][j] + 1, j, s ); cout << s[i][j] << "," << s[i][j] + 1; } int main() { int p[100]; int n; int m[100][100]; int s[100][100]; int count = 0; cin >> n; for( int i = 1; i <= n; i++ ) { cin >> p[count++]; cin >> p[count]; } MatrixChain( p, n, m, s ); for( int i = 0; i <= n; i++ ) { for( int j = 0; j <= n; j++ ) { if( m[i][j] < 0 ) { printf( "t-1" ); } else { printf( "t%2d", m[i][j] ); } } cout << endl; } system( "pause" ); return 0; }



