算法:矩阵连乘(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],现要将它们依次相乘,只能使用结合率,求最 ...
随机推荐
- centos8安装sersync为rsync实现实时同步
一,查看本地centos的版本: [root@localhost lib]# cat /etc/redhat-release CentOS Linux release 8.1.1911 (Core) ...
- requirements基本使用
requirements作用描述:很多 Python 项目中经常会包含一个 requirements.txt 文件,里面内容是项目的依赖包及其对应版本号的信息列表,即项目依赖关系清单,其作用是用来重新 ...
- centos 7.8 添加磁盘后查看、分区、格式化、挂载
基础环境 公有云 由于磁盘空间快用完了,现在决定多加一个40G磁盘 第一步 分区 fdisk -l #查看当前磁盘信息 fdisk /dev/vdb #对指定磁盘进行操作 如上图一般磁盘的第一个分区都 ...
- 第三十四章 Linux常规练习题(一)参考答案
一.练习题一 1.超级用户(管理员用户)提示符是___#_,普通用户提示符是___$_. 2.linux关机重启的命令有哪些 ? 关机命令 重启命令 shutdown -h now shutdown ...
- CentOS 8 关闭防火墙
SELINUX=disabled vim /etc/selinux/config systemctl disable firewalld.service
- skywalking8.1.0(一) 安装与部署
skywalking部署 背景介绍 目前公司后端服务全部为微服务并运行在kubernetes集群上,而大量的微服务的背后拥有很复杂的调用关系,纵使你是公司的资深开发也很难理清每一个后端服务之间的依赖关 ...
- 常用数据结构-集合(set)
集合(set)是python中最容易被忽视的.使用集合的主要好处在于速度快. 集合的一些特性: 集合元素不能重复 不支持索引访问集合中的元素 集合使用散列之后,可以在O(1)时间内访问元素 支持一些常 ...
- 已经编译安装的nginx/tenginx编译增加新模块
只适用于自行编译安装的nginx配置 业务变更带来的Nginx增加模块需求 由于业务从php转为go开发,需要用到Http2的协议.这种协议在Nginx上需要http_v2_module这个模块的支持 ...
- springboot data jdbc 数据库日期和查询出来的结果不一致
解决方法: 一.将serverTimezone=UTC改为CTT url: jdbc:mysql://localhost:3306/moviechoicesystem?serverTimezone=C ...
- 23longest-consecutive-sequence
题目描述 给定一个无序的整数类型数组,求最长的连续元素序列的长度. 例如: 给出的数组为[100, 4, 200, 1, 3, 2], 最长的连续元素序列为[1, 2, 3, 4]. 返回这个序列的长 ...