矩阵压缩降维动态规划递推【P1719 最大加权矩形】
矩陣壓縮&降維&動態規劃&遞推【P1719 最大加權矩形】
題目描述
為了更好的備戰NOIP2013,電腦組的幾個女孩子LYQ,ZSC,ZHQ認為,我們不光需要機房,我們還需要運動,于是就決定找校長申請一塊電腦組的課余運動場地,聽說她們都是電腦組的高手,校長沒有馬上答應他們,而是先給她們出了一道數學題,并且告訴她們:你們能獲得的運動場地的面積就是你們能找到的這個最大的數字。
校長先給他們一個N*N矩陣。要求矩陣中最大加權矩形,即矩陣的每一個元素都有一權值,權值定義在整數集上。從中找一矩形,矩形大小無限制,是其中包含的所有元素的和最大 。矩陣的每個元素屬于[-127,127],例如
0 –2 –7 0 9 2 –6 2 -4 1 –4 1 -1 8 0 –2在左下角:
9 2 -4 1 -1 8和為15。
幾個女孩子有點犯難了,于是就找到了電腦組精打細算的HZH,TZY小朋友幫忙計算,但是遺憾的是他們的答案都不一樣,涉及土地的事情我們可不能含糊,你能幫忙計算出校長所給的矩形中加權和最大的矩形嗎?
輸入格式
第一行:n,接下來是n行n列的矩陣。
輸出格式
最大矩形(子矩陣)的和。
輸入輸出樣例
輸入 #1
4 0 -2 -7 09 2 -6 2 -4 1 -4 1 -1 8 0 -2輸出 #1
15說明/提示
n<=120
代碼:
package com.sdutcm.tree.fourteen;import java.util.Scanner;public class P1719 {static Scanner sc =new Scanner(System.in);static int n=sc.nextInt();public static void main(String[] args) {int [][] arr= new int[n][n];for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {arr[i][j]=sc.nextInt();}}int max=0;for (int i = 0; i < n; i++) {//for (int j = i+1; j <n; j++) {int f[]=new int[n];for (int k = i; k <=j; k++) {for (int k2 = 0; k2 < n; k2++) {f[k2]+=arr[k][k2];}}max=Math.max(max, get(f));}}System.out.println(max);} //get函數是得到最大子段和private static int get(int[] f) {int now=0;int max=f[0];for (int i = 0; i < n; i++) {if(now>=0){now+=f[i];}else{now=f[i];} max=Math.max(max, now);}return max;}}詳細他人的講解:來源:https://www.luogu.com.cn/problem/solution/P1719
求最大字段和🏝
from:https://blog.csdn.net/qq_39098813/article/details/82054054
這個題目相信很多人都經常遇到,求一個數組的最大子數組和什么的,
首先給你一段數字 1、5、7、-2、-5、0;
讓你求最大字段和,從第一個數開始,統計目前累加的數的和是不是大于0 ,如果是大于0 則可以將下一個數字加進去,如果不大于0 就沒必要加了,之間從當前的數組開始一次新的累加,每次累加之后就和max進行一下比較,將max保存為最大值
/*** 獲取數組最大字段和** @param array* @return int*/public int getMax(int[] array) {int all = 0;//用于統計當前的數組和int max = array[0];//用于統計最大子數組和for (int i = 0; i < array.length; i++) {if (all >= 0) {all += array[i];//累加當前數組的和} else {all = array[i];}max = Math.max(all, max);//比較當前數組和與最大和之間的大小}return max;}矩陣壓縮:
? 這種思想真的很漂亮,首先,現將列枚舉相鄰組合,然后將同列相加,這樣的話,直接對這個數列進行最大子段和查找就可以了。相當于一張餅,先壓成一條線,再選最粗得那一段!
矩陣壓縮:
假設有一個矩陣:
-5 6 4
1 -2 6
2 1 -3
如何對它進行壓縮呢,其實不難,這邊我做一個類比,如果我們把一行看做一個數,這里看做三個數a,b,c,那么將這三個相鄰數的進行不同的組合,將這個新的組合視為一個新的數,這就是進行壓縮處理,例如a,b,c可以組合為{[a],[ab],[abc],[b],[bc],[c]},而矩陣壓縮也類似。
先設置一個變量max用于保存壓縮后的一維數組的最大子序列和。
第一次我們取第一行:
-5 6 4
則其最大子序列和為10,max=10。
第二次取第一二行:
-5 6 4
1 -2 6
注意現在開始是矩陣壓縮的精髓,我們將每一列的數進行相加,將多行變為一行。
第一列:-5+1=-4
第二列:6+(-2)=4
第三列:4+6=10
所以壓縮后的一維數組為:
-4 4 10
則其最大子序列和為14,max=14。
第三次取第一二三行:
-5 6 4
1 -2 6
2 1 -3
對每一列進行壓縮:
第一列:-5+1+2=-2
第二列:6+(-2)+1=5
第三列:4+6+(-3)=7
所以壓縮后的一維數組為:
-2 5 7
則其最大子序列和為12,max=14。
第四次取第二行:
1 -2 6
則其最大子序列和為6,max=14。
第五次取第二三行:
1 -2 6
2 1 -3
對每一列進行壓縮:
第一列:1+2=3
第二列:-2+1=-1
第三列:6+(-3)=3
所以壓縮后的一維數組為:
3 -1 3
則其最大子序列和為5,max=14。
第六次取第三行:
2 1 -3
則其最大子序列和為3,max=14。
最后求得這個矩陣最大的子矩陣和為14
也就是第一二行的三四列
6 4
-2 6
總結
以上是生活随笔為你收集整理的矩阵压缩降维动态规划递推【P1719 最大加权矩形】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世界上最神奇的数字:142857,看似平
- 下一篇: word停止工作 怎么解决