Monge矩阵

Monge矩阵

对一个m*n的实数矩阵A,如果对所有i,j,k和l,1≤ i<k ≤ m和1≤ j<l ≤ n,有 Ai,j+Ak,l ≤ Ai,l+Ak,j 那么,此矩阵A为Monge矩阵。

换句话说,每当我们从矩阵中挑出两行与两列,并且考虑行列交叉处的4个元素,左上角与右下角的和小于或等于左下角与右上角元素的和。

例如,下面这个就是一个Monge矩阵

(1)证明一个矩阵为Monge阵,当且仅当对所有i=1,2,...,m-1和j=1,2,...,n-1,有 Ai,j+Ai+1,j+1 ≤ Ai,j+1+Ai+1,j

(提示:在当部分,对行、列分别使用归纳法。)

(2)下面的矩阵不是Monge阵。改变一个元素,把它变成Monge矩阵

37 23 22 32

21 6 27 10

53 34 30 31

32 13 9 6

43 21 15 8

很明显是要改27,27可以改成【2,5】内的任何一个实数

(3)假设f(i)是第i行包含最左端最小值的列的索引值。证明对任何的m x n Monge矩阵,有f(1) ≤ f(2) ≤...≤ f(m)。

(4)下面是一个用来计算m x n 的Monge矩阵A中每一行的最左最小值的分治算法的描述:

构造一个包含所有A的偶数行的子矩阵A'。递归地计算A'中每一行的最左端最小值。然后计算A中奇数行的最左端最小值。

解释如何能在O(m+n)时间内计算出A的奇数行的最左端最小值?(在偶数行最左最小值已知的情况下)

解释:看下面的代码就很明显了。

其实这个算法,我个人感觉,就结构而言比较像分治,但是就思想而言比较像动态规划。

(5)写出(4)所描述算法的运行时间的递归式,并证明其解为O(m+nlogm)

T(m)=T(m/2)+ O(m+n)(求解略)

我的代码:

cpp 复制代码
#include<iostream>
using namespace std;

void calculate(double **A, int r1, int r2, int min, int max, int *f)	//计算f(r1)到f(r2)
{
	if (r1 > r2)return;
	int r = (r1 + r2) / 2;
	int result = min;
	int flag = A[r][min];
	for (int i = min + 1; i <= max; i++)	//寻找最左最小元素flag,和它的的下标result
	{
		if (A[r][i] < flag)
		{
			flag = A[r][i];
			result = i;
		}
	}
	f[r] = result;
	calculate(A, r1, r - 1, min, result, f);
	calculate(A, r + 1, r2, result, max, f);
}

bool isMonge(double **A, int m, int n)	//判断是否是Monge矩阵
{
	for (int i = 0; i < m - 1; i++)for (int j = 0; j < n - 1; j++)if (A[i][j] + A[i + 1][j + 1]>A[i + 1][j] + A[i][j + 1])return false;
	return true;
}
int main()
{
	int m, n;
	while (cin >> m >> n && m>1 && n > 1)
	{
		double **A = new double*[m];		//Monge矩阵
		int *f = new int[m];	//不需要在主函数里面进行初始化,这个工作由calculate函数完成
		for (int i = 0; i < m; i++)
		{
			A[i] = new double[n];
			for (int j = 0; j < n; j++)cin >> A[i][j];
		}
		if (isMonge(A, m, n))
		{
			cout << "这个是Monge矩阵" << endl;
			calculate(A, 0, m - 1, 0, n - 1, f);
			for (int i = 0; i < m; i++)cout << "第" << i << "行的最左最小元素的列下标是" << f[i] << endl;
		}
		else cout << "这个不是Monge矩阵";
	}
	return 0;
}
相关推荐
大明者省5 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_7987 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2587 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
知识分享小能手7 小时前
线性代数学习教程,从入门到精通,向量组的线性相关性 — 完整知识点梳理(7)
学习·线性代数·机器学习
Shell运维手记7 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI8 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型8 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光8 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院10 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡10 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构