算法:矩阵连乘(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],现要将它们依次相乘,只能使用结合率,求最 ...
随机推荐
- vm虚拟机设置共享文件夹不显示
1. 确认VMtools已经装好,开启共享文件夹,设置好共享目录 2.执行命令 sudo mount -t vmhgfs .host:/ /mnt/hgfs如果出现错误: Error: cannot ...
- centos 开机启动服务 systemctl
systemctl 实现开机自启服务 转载起一个好听的名字 最后发布于2018-06-26 13:49:06 阅读数 13473 收藏 展开 systemctl是RHEL 7 的服务管理工具中主要的 ...
- python 微信小程序自动化
微信小程序自动化 https://www.cnblogs.com/yyoba/python27 - FautoTesthttps://www.cnblogs.com/yyoba/p/9973731.h ...
- Unity-根据时间开灯与关灯
声明:本人只是学生,并且只是自学Unity,如有大神,不喜勿喷,不足之处,请指出! 本项目使用了UniStorm 3.0(天气)插件,时间也是调用它本身的API,实际并不影响,用系统的时间的是也是可以 ...
- Java接口的初始化
背景 接口与类真正有所区别的是前面讲述的四种"有且仅有"需要开始初始化场景中的第三种:当一个类在初始化时,要求其父类全部都已经初始化过了,但是一个接口在初始化时,并不要求其父接口全 ...
- 4. Validator校验器的五大核心组件,一个都不能少
困难是弹簧,你弱它就强.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众号[BAT的 ...
- 050_Dos命令
目录 Dos命令 打开Dos控制台 管理员方式运行 常用的Dos命令 Dos命令 打开Dos控制台 开始->附件->命令提示符 Window+R 输入cmd(推荐使用) 在任意文件夹下-& ...
- JSP标签语法、JSTL标签库、EL表达式辨析
<一.JSP > JSP 语法语法格式: <% 代码片段 %>或者<jsp:scriptlet> 代码片段</jsp:scriptlet> JSP声明 ...
- 从eclipse迁移到ideal
个人用eclipse比较多,什么Luna,Neon,Mars.几乎每年都要研发出一个版本.目前所在的这家公司,维护的是一个10年的老项目,需求迭代频率比较高,业务代码臃肿而难理解,依赖关系不清晰,代码 ...
- JQuery如何实现统计图表
EEP JQuery如何实现统计图表 讯光科技 前言 在ERP项目开发过程中,统计图表(chart)普遍应用于各种统计和报表中,其形象直观,内容清晰.EEP的JQuery网站项目使用了Easyui 插 ...