算法提高 矩阵乘法  
时间限制:3.0s   内存限制:256.0MB
    
问题描述
  有n个矩阵,大小分别为a0*a1, a1*a2, a2*a3, ..., a[n-1]*a[n],现要将它们依次相乘,只能使用结合率,求最少需要多少次运算。
  两个大小分别为p*q和q*r的矩阵相乘时的运算次数计为p*q*r。
输入格式
  输入的第一行包含一个整数n,表示矩阵的个数。
  第二行包含n+1个数,表示给定的矩阵。
输出格式
  输出一个整数,表示最少的运算次数。
样例输入
3
1 10 5 20
样例输出
150
数据规模和约定
  1<=n<=1000, 1<=ai<=10000。
本来赋的INF是0x3f3f3f,一直有两组过不了!
两个相邻的数字之说明这是一个矩阵,计算次数为0,当两个数字中间相隔一个数字的时候,计算次数为三者相乘。
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#define FOR(i,x,n) for(long i=x;i<n;i++)
#define ll long long int
#define INF 0x3f3f3f3f3f3f3f3f
#define MOD 1000000007
#define MAX_N 50005

using namespace std;

ll m[1005][1005];
ll a[1005];

int main()
{
    //freopen("input1.txt", "r", stdin);
    //freopen("data.out", "w", stdout);
    int N;
    scanf("%d",&N);
    FOR(i,0,N+1){
        scanf("%lld",&a[i]);
    }
    FOR(i,0,N+1){
        FOR(jj,0,N+1-i){
            int j=jj+i;
            if(i==0||i==1){
                m[jj][j]=0;
            }else if(i==2){
                m[jj][j]=a[jj]*a[jj+1]*a[j];
            }else if(i>2){
                ll minn=INF;
                FOR(k,jj+1,j){
                    if(k==jj+1){
                        ll t=m[k][j]+a[jj]*a[k]*a[j];
                        if(minn>t){
                            minn=t;
                        }
                    }else if(k==j-1){
                        ll t=m[jj][k]+a[jj]*a[k]*a[j];
                        if(minn>t){
                            minn=t;
                        }
                    }else{
                        ll t=m[jj][k]+m[k][j]+a[jj]*a[k]*a[j];
                        if(minn>t){
                            minn=t;
                        }
                    }
                }
                m[jj][j]=minn;
            }
        }
    }
    printf("%lld",m[0][N]);
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}