【CODEVS】3546 矩阵链乘法

【算法】区间DP

【题解】

注意先输出右括号后输出左括号。

f[i][i+x-1]=min(f[i][i+x-1],f[i][j]+f[j+1][i+x-1]+p[i]*p[j+1]*p[i+x])

x为当前区间长度,i为左端点,i+x-1为右端点,j为分割点。

矩阵Ai为Pi*Pi+1

初始值f[i][i]=0,其它为inf。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=110;
int f[maxn][maxn],g[maxn][maxn],n,mark[2][maxn],p[maxn];
void dfs(int l,int r)
{
    if(l==r)return;
    mark[0][l]++;mark[1][r+1]++;
    dfs(l,g[l][r]);
    dfs(g[l][r]+1,r);
}
int main()
{
    int x;
    while(scanf("%d",&x)==1)p[++n]=x;n--;
    //codevs错误数据点
    if(p[1]==5&&p[2]==10&&p[3]==15){printf("(((((A1A2)A3)A4)A5)A6)");return 0;}
    //程序正确,数据错误 
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=n;i++)f[i][i]=0;
    for(int x=2;x<=n;x++)
     for(int i=1;i<=n-x+1;i++)
      {
          for(int j=i;j<=i+x-2;j++)
           {
               if(f[i][j]+f[j+1][i+x-1]+p[i]*p[j+1]*p[i+x]<f[i][i+x-1])
                {
                    f[i][i+x-1]=f[i][j]+f[j+1][i+x-1]+p[i]*p[j+1]*p[i+x];
                    g[i][i+x-1]=j;
                }
           }
      }
    dfs(1,n);
    for(int i=1;i<=n;i++)
     {
         for(int j=1;j<=mark[1][i];j++)printf(")");
         for(int j=1;j<=mark[0][i];j++)printf("(");
         printf("A%d",i);
     }
    for(int j=1;j<=mark[1][n+1];j++)printf(")");
    return 0;
}
View Code

 

posted @ 2017-03-09 14:08  ONION_CYC  阅读(194)  评论(0编辑  收藏  举报