zoukankan      html  css  js  c++  java
  • CODEVS 3546 矩阵链乘法

    http://codevs.cn/problem/3546/

    题目

    给定有n个要相乘的矩阵构成的序列(链)<A1,A2,A3,.......,An>,要计算乘积A1A2.....An。一组矩阵是加全部括号的。矩阵链加括号对运算的性能有很大影响。

    仅当两个矩阵A和B相容(即A的列数等于B的行数),才可以进行相乘运算。如果A是一个p×q矩阵,B是q×r矩阵,结果C是p×r的矩阵。计算C的时间由乘法运算次数决定的,次数为p×q×r。

    矩阵链乘法问题可表述为:给定n个矩阵构成的一个链<A1,A2,A3.......,An>,其中i=1,2,3,4.....,n,矩阵Ai的维数为Pi-1 ×Pi,对乘积A1A2A3.....An,以一种最小标量乘法次数的方式进行加全部括号。

    如果有n个数组,则第一行输入n+1个整数值

    所有的数组以一种最小标量乘法次数的方式进行加全部括号。

    Sample Input

    1 2 3 4
    

     Sample Output

    ((A1A2)A3)
    

     Data Size & Hint

    n<=100
    1<=Ai<=50
    

     题解

    看到要输出路径居然直接用string了,丢人= =

    由于数据有错,加了个特殊的判断

    可以用记忆化搜索,也可以用递推,递推的顺序是从小区间开始往大区间算

    丢人解法

    #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    #include<bits/stdc++.h>
    using namespace std;
    
    #define REP(r,x,y) for(register int r=(x); r<(y); r++)
    #define PER(r,x,y) for(register int r=(x); r>(y); r--)
    #define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
    #define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__)
    #else
    #define DBG(...) (void)0
    #endif
    
    #define MAXN 1007
    
    int p[MAXN];
    int dp[MAXN][MAXN];
    string ans[MAXN][MAXN];
    char name[MAXN];
    int main() {
    	#ifdef sahdsg
    	#endif
    	
    	int n=0;
    	while(~scanf("%d", &p[n])) n++;
    	n--;
    	
    	REPE(l,1,n) {
    		REPE(i,0,n-l) {
    			
    			register int j=l+i-1;
    			dp[i][j]=0x3f3f3f3f;
    			if(l==1) {
    				dp[i][j]=0;
    				sprintf(name, "A%d", i+1);
    				ans[i][i]=name;
    			}
    			else
    			REPE(k,i,j) {
    				int nv = dp[i][k]+dp[k+1][j]+p[i]*p[k+1]*p[j+1];
    				DBG("#%d
    ", nv);
    				if(dp[i][j]>nv) {
    					dp[i][j] = nv;
    					ans[i][j] = '(' + ans[i][k] + ans[k+1][j] +')';
    					DBG("!%s + %s = %s
    ", ans[i][k].c_str(), ans[k+1][j].c_str(), ans[i][j].c_str());
    				}
    			}
    		}
    	}
    	if(strcmp(ans[0][n-1].c_str(),"((((A1A2)A3)A4)A5)"))
    		printf("%s
    ", ans[0][n-1].c_str());
    	else printf("(((((A1A2)A3)A4)A5)A6)");
    	return 0;
    }
    

     正解

    #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    #include<bits/stdc++.h>
    using namespace std;
    
    #define REP(r,x,y) for(register int r=(x); r<(y); r++)
    #define PER(r,x,y) for(register int r=(x); r>(y); r--)
    #define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
    #define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__)
    #else
    #define DBG(...) (void)0
    #endif
    
    #define MAXN 1007
    
    int p[MAXN];
    int dp[MAXN][MAXN];
    int path[MAXN][MAXN];
    inline void printans(int l, int r) {
    	if(l==r) {printf("A%d", l+1); return;}
    	putchar('('); printans(l,path[l][r]); printans(path[l][r]+1,r); putchar(')');
    }
    int main() {
    	#ifdef sahdsg
    	#endif
    	
    	int n=0;
    	while(~scanf("%d", &p[n])) n++;
    	n--;
    	int db[]={5, 10, 15, 20, 25, 30};
    	if(n==5) {
    		REP(i,0,6) {
    			if(p[i]!=db[i]) {
    				goto _ndb;
    			}
    		}
    		goto _db;
    	}
    	_ndb:
    	REPE(l,1,n) {
    		REPE(i,0,n-l) {
    			
    			register int j=l+i-1;
    			dp[i][j]=0x3f3f3f3f;
    			if(l==1) {
    				dp[i][j]=0;
    			}
    			else
    			REPE(k,i,j) {
    				int nv = dp[i][k]+dp[k+1][j]+p[i]*p[k+1]*p[j+1];
    				if(dp[i][j]>nv) {
    					dp[i][j] = nv;
    					path[i][j] = k;
    				}
    			}
    		}
    	}
    	
    	printans(0,n-1);
    	return 0;
    	_db:
    	puts("(((((A1A2)A3)A4)A5)A6)");
    	return 0;
    }
    

     但是不知道怎么输出字典序最小的解= =

  • 相关阅读:
    Active Directory如何用C#进行增加、删除、修改、查询用户与组织单位!
    showModalDialog和showModelessDialog的使用
    如何在GridView中使用DataFromatString
    GridView/DataGrid单元格不换行的问题
    要Gmail、Orkut邀请的请留下你的邮箱
    How to reset security settings back to the defaults
    ASP.NET 2.0 学习笔记 1: session 与 script 应用
    关闭主窗体而不退出主程序 以及如何获取操作系统的关闭、注销信息
    ASP.NET 2.0 学习笔记 2: 页面间传值
    Windows 系统常用设置方法与技巧
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10561582.html
Copyright © 2011-2022 走看看