• ZOJ 1276 "Optimal Array Multiplication Sequence"(最优矩阵链乘问题+区间DP)


    传送门

    •题意

      矩阵 A(n×m) 和矩阵 B(m×k) 相乘,共做 n×m×k 次乘法运算;

      给你 n 个矩阵,求这 n 个矩阵的最优结合方式,使得做的总乘法运算次数最少;

    •题解

      定义dp(i,j)表示第[i,...j]个矩阵的最小的乘法运算次数;

      定义d(i,j)表示第[i,...j]个矩阵的最优解从d(i,j)分开,即(Ai×Ai+1×......×Ad(i,j))×(Ad(i,j)+1×......×Aj);

      求解dp(i,j)的时候,求出最优解,并记录是从那个位置分开使得其最优;

      输出时递归输出即可;

    •Code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define INF 0x3f3f3f3f
     4 const int maxn=100;
     5 
     6 int n;
     7 int p[maxn];
     8 int dp[maxn][maxn];
     9 int d[maxn][maxn];
    10 
    11 void DP()
    12 {
    13     for(int len=2;len <= n;++len)
    14     {
    15         for(int i=1,j=i+len-1;j <= n;++i,++j)
    16         {
    17             for(int k=i;k < j;++k)
    18             {
    19                 int cur=dp[i][k]+dp[k+1][j]+p[i-1]*p[k]*p[j];
    20                 if(dp[i][j] > cur)
    21                 {
    22                     d[i][j]=k;
    23                     dp[i][j]=cur;
    24                 }
    25             }
    26         }
    27     }
    28 }
    29 void Print(int l,int r)
    30 {
    31     if(l == r)
    32     {
    33         printf("A%d",l);
    34         return ;
    35     }
    36     if(l > r)
    37         return ;
    38         
    39     printf("(");
    40     Print(l,d[l][r]);///[l,r]在d[l][r]处分割
    41     printf(" x ");
    42     Print(d[l][r]+1,r);
    43     printf(")");
    44 }
    45 void Solve()
    46 {
    47     for(int i=0;i <= n;++i)
    48         for(int j=0;j <= n;++j)
    49             dp[i][j]=(i == j ? 0:INF);
    50     DP();
    51     Print(1,n);
    52     printf("
    ");
    53 }
    54 int main()
    55 {
    56     int kase=1;
    57     while(~scanf("%d",&n) && n)
    58     {
    59         for(int i=1;i <= n;++i)///第i个矩阵的行和列为p[i-1],p[i]
    60         {
    61             int a,b;
    62             scanf("%d%d",&a,&b);
    63             p[i-1]=a;
    64             p[i]=b;
    65         }
    66         printf("Case %d: ",kase++);
    67         Solve();
    68     }
    69     return 0;
    70 }
    View Code
  • 相关阅读:
    【Nginx 快速入门】反向代理、负载均衡、动静分离
    【Redis】缓存穿透、缓存击穿、缓存雪崩(面试必备)
    【Redis】特殊数据类型
    【Redis】特殊数据类型
    【Redis】特殊数据类型
    typescript 技巧学习
    angular9的学习(十九)
    angular11源码探索二十六[Router整体路由配置]
    angular11源码探索二十五[Router路由事件]
    angular11源码探索二十四[路由检测变更策略]
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/11020912.html
Copyright © 2020-2023  润新知