• SHUOJ


    链接:http://acmoj.shu.edu.cn/problem/24/

    分析:设(dp[i][j])为矩阵(A[i:j])所需的最少乘法次数,则有dp方程:(dp[i][j]=min{dp[i][k]+dp[k+1][j]}(ileq k <j)),当(i=j)时,(dp[i][j]=0).
    则可以递归求解该问题,递归终止的条件是(i=j),自底向上地解决问题。枚举([i,j))之间的每个k,并取其最小值。
    因为该题需要输出解决方案,所以求解时,若(dp[i][j] = dp[i][k]+dp[k+1][j]),则用数组(path[i][j])记录下这个k。
    输出结果时,仍采用递归的方式,将一个括号内的视作一个子结构,递归终止的条件是区间中的元素仅有一个,此时打印单个矩阵。注意除了最外层的区间不用输出括号,加特判即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e2+5;
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    int a[maxn],b[maxn];
    LL dp[maxn][maxn];
    int path[maxn][maxn];
    int n;
    int dfs(int i,int j)
    {
        LL &ans=dp[i][j];
        if(ans<INF) return ans;
        if(i==j) return ans=0;
        for(int k=i;k<j;k++){
            int tmp=dfs(i,k)+dfs(k+1,j)+a[i]*b[k]*b[j];     //递归求解
            if(tmp<ans){
                ans=tmp;                                    //不断更新最小值和其路径
                path[i][j]=k;                               
            }
        }
        return ans;
    }
    
    void print(int i,int j)
    {
        if(i==j){                     //递归终止
            printf("A%d",i);          //输出独立矩阵
            return;
        }
        if(i>1||j<n) printf("(");     //最外层不要括号  
        print(i,path[i][j]);          //递归进入子区间
        print(path[i][j]+1,j);
        if(i>1||j<n) printf(")");    //最外层不要括号
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int cas=0;
        while(scanf("%d",&n)==1){
            for(int i=1;i<=n+1;i++){
                scanf("%d",&a[i]);
                if(i>1) b[i-1] = a[i];      //后一个矩阵的行数等于前一个矩阵的列数
            }
            memset(dp,INF,sizeof(dp));      //初值置无穷大
            memset(path,0,sizeof(path));    //路径
            dp[1][n]=dfs(1,n);
            printf("Case %d
    ",++cas);
            printf("%lld ",dp[1][n]);
            print(1,n);
            printf("
    ");
        }
        return 0;
    }
    
    
    为了更好的明天
  • 相关阅读:
    7.13dfs例题:部分和
    7.12dfs例题:数独游戏
    1.2题解:如何找数组中唯一成对的那个数(位运算)
    左程云Java算法(1)
    SQL基本语句增删改查
    Python spyder Ipython console 连接失败问题
    VBA——Msgbox
    python 字符串
    Scrapy-selectors总结
    文字单行居中,多行居左/居右
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9708937.html
Copyright © 2020-2023  润新知