算法:矩阵连乘(Java)动态规划
Description
给你2个矩阵A、B,我们使用标准的矩阵相乘定义C=AB如下: A数组中栏(column)的数目一定要等于B数组中列(row)的数目才可以做此2数组的相乘。若我们以rows(A),columns(A)分 别代表A数组中列及栏的数目,要计算C数组共需要的乘法的数目为:rows(A)columns(B)columns(A)。例如:A数组是一个 10x20的矩阵,B数组是个20x15的矩阵,那么要算出C数组需要做101520,也就是3000次乘法。 要计算超过2个以上的矩阵相乘就得决定要用怎样的顺序来做。
例如:X、Y、Z都是矩阵,要计算XYZ的话可以有2种选择:(XY)Z 或者 X(YZ)。
假设X是5x10的数组,Y是10x20的数组,Z是20x35的数组,那个不同的运算顺序所需的乘法数会有不同:
(XY)Z
- 5 * 20 * 10 = 1000次乘法完成(XY),并得到一5x20的数组。
- 5 * 35 * 20 = 3500次乘法得到最后的结果。
- 总共需要的乘法的次数:1000+3500=4500。
X(YZ)
- 10 * 35 * 20 = 7000次乘法完成(YZ),并得到一10x35的数组。
- 5 * 35 * 10 = 1750次乘法得到最后的结果。
- 总共需要的乘法的次数:7000 +1750 = 8750。
很明显的,我们可以知道计算(XY)Z会使用较少次的乘法。 这个问题是:给你一些矩阵,你要写一个程序来决定该如何相乘的顺序,使得用到乘法的次数会最少。
Input
含有多组测试数据,每组测试数据的第一列,含有1个整数N(N <= 10)代表有多少个数组要相乘。接下来有N对整数,代表一数组的列数及栏数。这N个数组的顺序与要你相乘的数组顺序是一样的。N=0代表输入结束。请参考Sample Input。
Output
每组测试数据输出一列,内容为矩阵相乘的顺序(以刮号来表示)使得所用的乘法次数最小。如果有不只一组答案,输出任一组均可。请参考Sample Output。
Sample Input
3
1 5
5 20
20 1
3
5 10
10 20
20 35
6
30 35
35 15
15 5
5 10
10 20
20 25
0
Sample Output
Case 1: (A1 x (A2 x A3))
Case 2: ((A1 x A2) x A3)
Case 3: ((A1 x (A2 x A3)) x ((A4 x A5) x A6))
递归关系:
数组m[n][n]存储最优值
数组s[n][n]存储最优时分割的位置
import java.util.Scanner;
public class Main {
static int count = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int p[], m[][], s[][];
while (sc.hasNextInt()) {
int n = sc.nextInt();
if (n == 0)
break;
p = new int[n + 1];
m = new int[n + 1][n + 1];
s = new int[n + 1][n + 1];
for (int i = 0; i < n; i++) {
p[i] = sc.nextInt();
p[i + 1] = sc.nextInt();
}
matrixChain(p, m, s);
System.out.printf("Case %d: ", ++count);
print(1, n, s);
System.out.print('\n');
// printmAnds(n, m, s);
}
sc.close();
}
public static void matrixChain(int p[], int m[][], int s[][]) {
int n = p.length - 1;
for (int i = 1; i <= n; i++)
m[i][i] = 0;
for (int r = 2; r <= n; r++) {
for (int i = 1; i <= n - r + 1; i++) {
int j = i + r - 1;
m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j];
s[i][j] = i;
for (int k = i + 1; k < j; k++) {
int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (t < m[i][j]) {
m[i][j] = t;
s[i][j] = k;
}
}
}
}
}
public static void print(int i, int j, int s[][]) {
if (i == j) {
System.out.print("A" + i);
return;
}
else {
System.out.print("(");
print(i, s[i][j], s);
System.out.print(" x ");
print(s[i][j] + 1, j, s);
System.out.print(")");
}
}
// public static void printmAnds(int n, int m[][], int s[][]){
// System.out.printf("m[%d][%d]: \n", n, n);
// for (int i = 1; i <= n; i++) {
// System.out.print(m[i][1]);
// for (int j = 2; j <= n; j++) {
// System.out.print("\t" + m[i][j]);
// }
// System.out.print('\n');
// }
//
// System.out.printf("s[%d][%d]: \n", n, n);
// for (int i = 1; i <= n; i++) {
// System.out.print(s[i][1]);
// for (int j = 2; j <= n; j++) {
// System.out.print("\t" + s[i][j]);
// }
// System.out.print('\n');
// }
// }
}
算法:矩阵连乘(Java)动态规划的更多相关文章
- 【BZOJ1009】GT考试(KMP算法,矩阵快速幂,动态规划)
[BZOJ1009]GT考试(KMP算法,矩阵快速幂,动态规划) 题面 BZOJ 题解 看到这个题目 化简一下题意 长度为\(n\)的,由\(0-9\)组成的字符串中 不含串\(s\)的串的数量有几个 ...
- TextRank算法提取关键词的Java实现
转载:码农场 » TextRank算法提取关键词的Java实现 谈起自动摘要算法,常见的并且最易实现的当属TF-IDF,但是感觉TF-IDF效果一般,不如TextRank好. TextRank是在 G ...
- 【BZOJ4000】[TJOI2015]棋盘(矩阵快速幂,动态规划)
[BZOJ4000][TJOI2015]棋盘(矩阵快速幂,动态规划) 题面 BZOJ 洛谷 题解 发现所有的东西都是从\(0\)开始编号的,所以状压只需要压一行就行了. 然后就可以随意矩乘了. #in ...
- 【BZOJ4832】抵制克苏恩(矩阵快速幂,动态规划)
[BZOJ4832]抵制克苏恩(矩阵快速幂,动态规划) 题面 BZOJ 题解 一模一样 #include<iostream> #include<cstdio> using na ...
- 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)
[UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...
- 【BZOJ1898】[ZJOI2005]沼泽鳄鱼(矩阵快速幂,动态规划)
[BZOJ1898][ZJOI2005]沼泽鳄鱼(矩阵快速幂,动态规划) 题面 BZOJ 洛谷 题解 先吐槽,说好了的鳄鱼呢,题面里面全是食人鱼 看到数据范围一眼想到矩乘. 先不考虑食人鱼的问题,直接 ...
- 算法笔记_071:SPFA算法简单介绍(Java)
目录 1 问题描述 2 解决方案 2.1 具体编码 1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...
- 常用的排序算法介绍和在JAVA的实现(二)
一.写随笔的原因:本文接上次的常用的排序算法介绍和在JAVA的实现(一) 二.具体的内容: 3.交换排序 交换排序:通过交换元素之间的位置来实现排序. 交换排序又可细分为:冒泡排序,快速排序 (1)冒 ...
- 算法笔记_081:蓝桥杯练习 算法提高 矩阵乘法(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 有n个矩阵,大小分别为a0*a1, a1*a2, a2*a3, ..., a[n-1]*a[n],现要将它们依次相乘,只能使用结合率,求最 ...
随机推荐
- Linux如何在vim里搜索关键字
例如搜索 the写法:/the +回车 /+关键字 ,回车即可.此为从文档当前位置向下查找关键字,按n键查找关键字下一个位置: ?+关键字,回车即可.此为从文档挡圈位置向上查找关键字,按n键向 ...
- 往with as中写入数据的方法
方法1:直接写入,使用union all,简单直观,但程序运行效率低,几百条就很慢了 with dw_wms_outbound_info_v100 as( select '10700001' as o ...
- 51nod 最大M子段和系列(1052、1053、1115)
51nod1052 数据量小,可使用O(N*M)的DPAC,递推公式: dp[i][j]=max(dp[i-1][j-1], dp[i][j-1])+a[j]; dp[i][j]表示前j个数取 i 段 ...
- 雨露均沾的OkHttp—WebSocket长连接的使用&源码解析
前言 最近老板又来新需求了,要做一个物联网相关的app,其中有个需求是客户端需要收发服务器不定期发出的消息. 内心OS:
- c++ 获取当前时间周初凌晨时间戳(获取当前时间周一凌晨时间戳)
UINT64 GetWeekBeginTime(){ time_t t; t = time(0); tm* t_tm = localtime(&t); t_tm->tm_hour = 0 ...
- oracle索引失效情况(转)
1.隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给Orac ...
- 1.1:JAVA基础
JAVA基础面试部分(多线程.算法.网络编程提出去了,详细分类见<面经>) 一.Java底层基础题 JDK和JRE区别? 1.JDK是整个JAVA的核心,包括了Java运行环境JRE,一堆 ...
- 使用 beeline 连接 hive 数据库报错处理
一.beeline连接hive报错 1. User: root is not allowed to impersonate root (state=08S01,code=0) 在初次搭建完hadoop ...
- 关于oracle监听程序的相关问题及解决方法
1.查看监听程序是否启动 打开cmd窗口,cmd用管理员运行,否则无法执行启动与停止监听命令 lsnrctl status查看运行状态 lsnrctl stop停止监听 lsnrctl start启动 ...
- 【Spring Cloud + Vue 有来商城】研发小组开发规范全方位梳理
项目演示 后端 Spring Cloud实战 | 第一篇:Windows搭建Nacos服务 Spring Cloud实战 | 第二篇:Spring Cloud整合Nacos实现注册中心 Spring ...