动态规划--(矩阵连乘 类似poj1651 )

poj1651:

题的大意是:给出一组N个数,每次从中抽出一个数(第一和最后一个不能抽)

 ,该次的得分即为抽出的数与相邻两个数的乘积。直到只剩下首尾两个数为止。问最小得分是多少?

这是一个矩阵连乘的稍稍变形:

Input

The first line of the input contains the number of cards N (3 <= N <= 100). The second line contains N integers in the range from 1 to 100, separated by spaces.

Output

Output must contain a single integer – the minimal score.

Sample Input

6
10 1 50 50 20 5

Sample Output

3650

一个经典题目:

#include <iostream>
#define NUM 105
using namespace std;


int main()
{
    int D[NUM];
    int N;
    cin>>N;
    int dp[NUM][NUM];
    N--;
    for(int i = 0;i<=N;i++)
        cin>>D[i];
//    for(int i = 1;i<=N+1;i++)
//        cout <<D[i]<<" ";
//    cout <<endl;

    for(int i = 0;i<=N+1;i++)
        dp[i][i] = 0;//如果是只有一个矩阵,连乘就是一个0;
                     //子问题的规模r = 1的时候;


    for(int r = 2;r<=N;r++){//r为当前计算的链长;(子问题的规模)




        for(int i =1 ;i<=N-r+1;i++){//n-r+1为最后一个r链长的前边界;
            int j = i+r-1;//计算前边界为i长为r链的后边界;

                //初始化dp[i][j];也就是划分为Ai(Ai+1..Aj)
            dp[i][j] = dp[i+1][j]+D[i-1]*D[i]*D[j];

            for(int k = i+1;k<=j-1;k++){
                dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+D[i-1]*D[k]*D[j]);//划分为其他的时候;并且用最好的值替换;
            }
        }
    }
//    for(int i = 0;i<=N;i++){
//        for(int j  = 0;j<=N;j++)
//            cout <<dp[i][j]<<" ";
//        cout <<endl;
//    }//测试dp;
    cout<<dp[1][N]<<endl;

    return 0;
}
点赞