前言
游戏规则:矩阵之间的连乘与数的连乘或连加不同,不同的 连乘的顺序 最终计算的次数也不同。如下
一、穷举法与备忘库法
1、穷举法
列举所以的可能的计算次序,计算所有的计算次序所用的次数,然后找出最少的计算次序。
2、备忘录法
存在很多子问题已经别求解,通过数组存储已经求解的问题,递归求解之前,先检查是否已经求解,如果已经求解,直接使用。
private static int lookupChain(int i, int j) {
//int u=0;
if(m[i][j]>0) return m[i][j];
if(i==j) return 0;
int t = lookupChain(i+1,j) +p[i-1]*p[i]*p[j];
s[i][j] = i;
for (int k = i+1; k < j; k++) {
int z = lookupChain(i,k) +lookupChain(k+1,j) +p[i-1]*p[k]*p[j];
if(z<t) {
t=z;s[i][j] = k;
}
}
m[i][j] = t;
return t;
}
二、动态规划法
1、分析最优解的结构
- 计算A[i : j]的最优解,包括A[i : k] ,A[k+1 : j]也是最优解。——最优子结构性质。
2、建立最优子结构
-
计算A[i : j] 1<=i<=j<=n 所需的最少数乘次数为m[i][j],原问题的最优解为m[1][n].
-
当i=j,A[i;j] = Ai,m[i][j] = 0。
-
当i<j, m[i,j]= m[i,k]+ m[k +1, j]+ P[i-1]P[k]P [j]。k的位置只有j-i种可能。
-
递归定义m[i][j]:
3、计算最优值
private static void lookupChain1(int n) {
for (int i = 0; i <n ; i++) mm[i][i] = 0;
for (int r = 2; r <n ; r++) {
for(int i=1;i<n-r+1;i++) {
int j=i+r-1;//p[i]*p[i+1]*p[j];
mm[i][j] = mm[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(int k=i+1;k<j;k++) {//p[i]*p[k]*p[j]
int t = mm[i][k]+mm[k+1][j]+p[i-1]*p[k]*p[j];
if(t<mm[i][j]) {
mm[i][j] = t;
s[i][j] = k;
}
}
}
}
}