当前位置: 首页 > news >正文

asp网站如何运行教程网网站源码php

asp网站如何运行,教程网网站源码php,怎么建设一个优秀的网站,泰安新闻频道在线直播【华为OD】最大子矩阵和 题目描述 给定一个二维整数矩阵,要在这个矩阵中选出一个子矩阵,使得这个子矩阵内所有的数字和尽量大。我们把这个子矩阵称为"和最大子矩阵",子矩阵的选取原则,是原矩阵中一段相互连续的矩形区域…

【华为OD】最大子矩阵和

题目描述

给定一个二维整数矩阵,要在这个矩阵中选出一个子矩阵,使得这个子矩阵内所有的数字和尽量大。我们把这个子矩阵称为"和最大子矩阵",子矩阵的选取原则,是原矩阵中一段相互连续的矩形区域。

输入描述

  • 输入的第一行包含两个整数 N,M (1 <= N, M <= 10)
  • 表示一个 N 行 M 列的矩阵
  • 下面有 N 行,每行有 M 个整数
  • 同一行中每两个数字之间有一个空格
  • 最后一个数字后面没有空格
  • 所有的数字得在 -1000 ~ 1000 之间

输出描述

输出一行,一个数字。表示选出的"和最大子矩阵"内所有数字的和

示例

输入:

3 4
-3 5 -1 5
2 4 -2 4
-1 3 -1 3

输出:

20

说明:
一个3*4的矩阵中后面3列的和为20,和最大

解题思路

这是一个经典的最大子矩阵和问题,是最大子数组和问题在二维空间的扩展。

核心思想:

  1. 枚举所有可能的上下边界
  2. 对于每一对上下边界,将问题转化为一维的最大子数组和问题
  3. 使用Kadane算法求解一维最大子数组和

我将提供两种解法:暴力枚举法优化的Kadane算法

解法一:暴力枚举法

暴力枚举所有可能的子矩阵,计算每个子矩阵的和,找出最大值。

Java实现

import java.util.*;public class Solution1 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int[][] matrix = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {matrix[i][j] = sc.nextInt();}}int maxSum = Integer.MIN_VALUE;// 枚举所有可能的子矩阵for (int r1 = 0; r1 < n; r1++) {for (int c1 = 0; c1 < m; c1++) {for (int r2 = r1; r2 < n; r2++) {for (int c2 = c1; c2 < m; c2++) {// 计算子矩阵 (r1,c1) 到 (r2,c2) 的和int sum = 0;for (int i = r1; i <= r2; i++) {for (int j = c1; j <= c2; j++) {sum += matrix[i][j];}}maxSum = Math.max(maxSum, sum);}}}}System.out.println(maxSum);}
}

Python实现

def solve_brute_force():n, m = map(int, input().split())matrix = []for _ in range(n):row = list(map(int, input().split()))matrix.append(row)max_sum = float('-inf')# 枚举所有可能的子矩阵for r1 in range(n):for c1 in range(m):for r2 in range(r1, n):for c2 in range(c1, m):# 计算子矩阵 (r1,c1) 到 (r2,c2) 的和current_sum = 0for i in range(r1, r2 + 1):for j in range(c1, c2 + 1):current_sum += matrix[i][j]max_sum = max(max_sum, current_sum)print(max_sum)solve_brute_force()

C++实现

#include <iostream>
#include <vector>
#include <climits>
using namespace std;int main() {int n, m;cin >> n >> m;vector<vector<int>> matrix(n, vector<int>(m));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> matrix[i][j];}}int maxSum = INT_MIN;// 枚举所有可能的子矩阵for (int r1 = 0; r1 < n; r1++) {for (int c1 = 0; c1 < m; c1++) {for (int r2 = r1; r2 < n; r2++) {for (int c2 = c1; c2 < m; c2++) {// 计算子矩阵 (r1,c1) 到 (r2,c2) 的和int sum = 0;for (int i = r1; i <= r2; i++) {for (int j = c1; j <= c2; j++) {sum += matrix[i][j];}}maxSum = max(maxSum, sum);}}}}cout << maxSum << endl;return 0;
}

解法二:Kadane算法优化

通过固定上下边界,将二维问题转化为一维最大子数组和问题,使用Kadane算法求解。

Java实现

import java.util.*;public class Solution2 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int[][] matrix = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {matrix[i][j] = sc.nextInt();}}int maxSum = Integer.MIN_VALUE;// 枚举所有可能的上下边界for (int top = 0; top < n; top++) {int[] temp = new int[m];for (int bottom = top; bottom < n; bottom++) {// 将第bottom行加到temp数组中for (int j = 0; j < m; j++) {temp[j] += matrix[bottom][j];}// 对temp数组使用Kadane算法找最大子数组和int currentMax = kadane(temp);maxSum = Math.max(maxSum, currentMax);}}System.out.println(maxSum);}// Kadane算法求最大子数组和private static int kadane(int[] arr) {int maxSoFar = arr[0];int maxEndingHere = arr[0];for (int i = 1; i < arr.length; i++) {maxEndingHere = Math.max(arr[i], maxEndingHere + arr[i]);maxSoFar = Math.max(maxSoFar, maxEndingHere);}return maxSoFar;}
}

Python实现

def kadane(arr):"""Kadane算法求最大子数组和"""max_so_far = arr[0]max_ending_here = arr[0]for i in range(1, len(arr)):max_ending_here = max(arr[i], max_ending_here + arr[i])max_so_far = max(max_so_far, max_ending_here)return max_so_fardef solve_kadane():n, m = map(int, input().split())matrix = []for _ in range(n):row = list(map(int, input().split()))matrix.append(row)max_sum = float('-inf')# 枚举所有可能的上下边界for top in range(n):temp = [0] * mfor bottom in range(top, n):# 将第bottom行加到temp数组中for j in range(m):temp[j] += matrix[bottom][j]# 对temp数组使用Kadane算法找最大子数组和current_max = kadane(temp)max_sum = max(max_sum, current_max)print(max_sum)solve_kadane()

C++实现

#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;// Kadane算法求最大子数组和
int kadane(vector<int>& arr) {int maxSoFar = arr[0];int maxEndingHere = arr[0];for (int i = 1; i < arr.size(); i++) {maxEndingHere = max(arr[i], maxEndingHere + arr[i]);maxSoFar = max(maxSoFar, maxEndingHere);}return maxSoFar;
}int main() {int n, m;cin >> n >> m;vector<vector<int>> matrix(n, vector<int>(m));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> matrix[i][j];}}int maxSum = INT_MIN;// 枚举所有可能的上下边界for (int top = 0; top < n; top++) {vector<int> temp(m, 0);for (int bottom = top; bottom < n; bottom++) {// 将第bottom行加到temp数组中for (int j = 0; j < m; j++) {temp[j] += matrix[bottom][j];}// 对temp数组使用Kadane算法找最大子数组和int currentMax = kadane(temp);maxSum = max(maxSum, currentMax);}}cout << maxSum << endl;return 0;
}

解法三:前缀和优化(额外解法)

使用二维前缀和来快速计算任意子矩阵的和。

Java实现

import java.util.*;public class Solution3 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int[][] matrix = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {matrix[i][j] = sc.nextInt();}}// 构建前缀和数组int[][] prefixSum = new int[n + 1][m + 1];for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {prefixSum[i][j] = matrix[i-1][j-1] + prefixSum[i-1][j] + prefixSum[i][j-1] - prefixSum[i-1][j-1];}}int maxSum = Integer.MIN_VALUE;// 枚举所有可能的子矩阵for (int r1 = 0; r1 < n; r1++) {for (int c1 = 0; c1 < m; c1++) {for (int r2 = r1; r2 < n; r2++) {for (int c2 = c1; c2 < m; c2++) {// 使用前缀和快速计算子矩阵和int sum = prefixSum[r2+1][c2+1] - prefixSum[r1][c2+1] - prefixSum[r2+1][c1] + prefixSum[r1][c1];maxSum = Math.max(maxSum, sum);}}}}System.out.println(maxSum);}
}

Python实现

def solve_prefix_sum():n, m = map(int, input().split())matrix = []for _ in range(n):row = list(map(int, input().split()))matrix.append(row)# 构建前缀和数组prefix_sum = [[0] * (m + 1) for _ in range(n + 1)]for i in range(1, n + 1):for j in range(1, m + 1):prefix_sum[i][j] = (matrix[i-1][j-1] + prefix_sum[i-1][j] + prefix_sum[i][j-1] - prefix_sum[i-1][j-1])max_sum = float('-inf')# 枚举所有可能的子矩阵for r1 in range(n):for c1 in range(m):for r2 in range(r1, n):for c2 in range(c1, m):# 使用前缀和快速计算子矩阵和current_sum = (prefix_sum[r2+1][c2+1] - prefix_sum[r1][c2+1] - prefix_sum[r2+1][c1] + prefix_sum[r1][c1])max_sum = max(max_sum, current_sum)print(max_sum)solve_prefix_sum()

C++实现

#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;int main() {int n, m;cin >> n >> m;vector<vector<int>> matrix(n, vector<int>(m));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> matrix[i][j];}}// 构建前缀和数组vector<vector<int>> prefixSum(n + 1, vector<int>(m + 1, 0));for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {prefixSum[i][j] = matrix[i-1][j-1] + prefixSum[i-1][j] + prefixSum[i][j-1] - prefixSum[i-1][j-1];}}int maxSum = INT_MIN;// 枚举所有可能的子矩阵for (int r1 = 0; r1 < n; r1++) {for (int c1 = 0; c1 < m; c1++) {for (int r2 = r1; r2 < n; r2++) {for (int c2 = c1; c2 < m; c2++) {// 使用前缀和快速计算子矩阵和int sum = prefixSum[r2+1][c2+1] - prefixSum[r1][c2+1] - prefixSum[r2+1][c1] + prefixSum[r1][c1];maxSum = max(maxSum, sum);}}}}cout << maxSum << endl;return 0;
}

算法复杂度分析

解法一:暴力枚举法

  • 时间复杂度:O(N²M²(N+M)),六重循环
  • 空间复杂度:O(1)

解法二:Kadane算法优化

  • 时间复杂度:O(N²M),三重循环
  • 空间复杂度:O(M)

解法三:前缀和优化

  • 时间复杂度:O(N²M²),四重循环但每次计算子矩阵和为O(1)
  • 空间复杂度:O(NM)

示例分析

对于给定的示例:

3 4
-3  5 -1  52  4 -2  4
-1  3 -1  3

最大子矩阵是后面3列的所有元素:

 5 -1  5    (第1行后3列)4 -2  4    (第2行后3列)3 -1  3    (第3行后3列)

和为:5 + (-1) + 5 + 4 + (-2) + 4 + 3 + (-1) + 3 = 20

总结

三种解法各有特点:

  1. 暴力枚举法:思路简单直观,但时间复杂度较高
  2. Kadane算法优化:是最优解法,时间复杂度最低,推荐使用
  3. 前缀和优化:在某些场景下有优势,特别是需要多次查询时

对于这道题目,由于N, M ≤ 10,数据规模较小,三种方法都能通过。但在实际应用中,Kadane算法优化是最佳选择,它将二维问题巧妙地转化为一维问题,大大降低了时间复杂度。

http://www.dtcms.com/a/447954.html

相关文章:

  • 整站下载器 做网站地图重庆假山制作
  • 做网页要去哪个网站佛山网站建设收费标准
  • 国外好的设计网站有哪些深圳专业做网站哪家专业
  • 如何编写网站后台程序移动网站建设方面
  • wordpress整站手机端网游推广员
  • RAG检索增强LLM
  • 建设网站的内容规划镇江网站推广排名
  • 物业公司网站建设网站源码修改后怎么提交
  • 手机响应式网站页面升级紧急通知自动跳转中
  • 1如何做网站推广微信公众号运营一年多少钱
  • 今日八股——JUC篇
  • 百度网站优化软件网站建设除了凡科还有哪些
  • 【算法训练营Day30】动态规划part6
  • 网页好看的网站设计公司网络推广网站就选火13星仁德
  • wordpress 企业整站源码汕头智能模板建站
  • php网站的数据库怎么做备份制作简历模板网站
  • 做网站打电话怎么和客户说宝安做网站公司
  • 三维在线设计网站电子商务网站建设与管理课后心得
  • 南昌企业网站建设公司北京网站设计课程
  • 驻马店怎么建设自己的网站安装wordpress视频教程
  • 做网站市场分析分类目录网站大全做seo
  • 大型门户网站建设 费用网站开发前景知乎
  • 广州建站软件wordpress在线制作网页
  • 晟合建设集团网站免费原创视频素材
  • 网站建设自身优势的分析从零自学编程免费
  • 律所网站建设深圳网站制作价格
  • 网站备案号填写wordpress 自媒体主题
  • 公司网站建设团队已经有了域名和服务器怎么做网站
  • 小购物网站建设WordPress微信强制跳转插件
  • 咨询公司网站模板大连金石滩