zoukankan      html  css  js  c++  java
  • 【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
  • 相关阅读:
    读《大道至简—编程的精义》有感
    c++ 指针做为参数和返回值
    c++ 函数
    c++ 分配与释放内存
    c++ 以多维数组的形式访问动态内存
    c++ 动态数组,指针与动态内存分配
    c++ 指针访问数组
    c++ 常量指针
    c++ 指针
    c++ 字符串转换
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6525391.html
Copyright © 2011-2022 走看看