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#小型资源管理器
    codeforces #310 div1 B
    codeforces #310 div1 A
    BZOJ 1030 文本生成器
    BZOJ 2806 cheat
    BZOJ 2553 禁忌
    BZOJ 4199 品酒大会
    codeforces #309 div1 D
    codeforces #309 div1 C
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6525391.html
Copyright © 2011-2022 走看看