poj 1651 Multiplication Puzzle 矩阵链乘问题

来源:互联网 发布:php企业站 编辑:程序博客网 时间:2024/06/06 07:43
题目:点击打开链接
大意:n张写着数字的卡片排成一行,除了第一张和第二张不能拿,每次拿走其中一张卡片,拿走卡片时得分是此卡乘以左右俩个边的乘积,最后只剩下一张,求所得的分数最大。我刚开始接触动态规划,不知道怎做,查了一下,是矩阵链乘,感觉不错,就好好研究一下吧。
分析:如果知道矩阵链乘的一定会知道为什么是矩阵链乘,没见过的可以看一下我总结的《矩阵链乘》那篇文章。这道题就是个模板题,会了矩阵链乘就很简单了。

代码:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MAX=105;const int INF=0x3f3f3f3f;int a[MAX];int d[MAX][MAX];int n;void matrix_chain(){    for(int i=0;i<n;i++)//memset(d,0,sizeof(d));也可以这样来初始化,简单        d[i][i]=0;     //因为一个矩阵自身肯定不能相乘的    for(int t=1;t<n;t++){ //计算t+1个矩阵连乘的情况        for(int i=1,j=t+1;j<n;i++,j++){ //j从多少开始取决于t和i            int minn=INF;            for(int k=i;k<j;k++){ //k相当于拿出的那张卡片,k在(i,j)区间枚举                int temp=d[i][k]+d[k+1][j]+a[i-1]*a[k]*a[j];                if(temp<minn)minn=temp;            }            d[i][j]=minn; //记录(i,j)区间的最小值        }    }    cout<<d[1][n-1]<<endl;}int main(){    while(cin>>n){        for(int i=0;i<n;i++)            cin>>a[i];        matrix_chain();    }    return 0;}

其中需要注意的一点是t,i,j 三者的取值关系是相关的,如果t 从2开始取值,则j=t 而不是t+1 可以试一下


0 0