Java 使用动态规划查找最大大小排序子矩阵
我试图解决一个动态规划问题,包括一个矩阵,找到最大大小排序的子矩阵 我想用dinamic编程来找到解决方案,但没有得到正确的结果 我的程序由两种方法组成:第一种方法递归地检查元素附近的参数给定的位置。然后,在第二种方法中,我调用前一种方法来查找子矩阵的最大阶数,但它没有返回正确的结果 例如,对于这个矩阵,使用新的解决方案调用类(5,6) 它应该返回4。 这是我的密码:Java 使用动态规划查找最大大小排序子矩阵,java,algorithm,dynamic-programming,Java,Algorithm,Dynamic Programming,我试图解决一个动态规划问题,包括一个矩阵,找到最大大小排序的子矩阵 我想用dinamic编程来找到解决方案,但没有得到正确的结果 我的程序由两种方法组成:第一种方法递归地检查元素附近的参数给定的位置。然后,在第二种方法中,我调用前一种方法来查找子矩阵的最大阶数,但它没有返回正确的结果 例如,对于这个矩阵,使用新的解决方案调用类(5,6) 它应该返回4。 这是我的密码: import java.util.Scanner; public class Solution { private i
import java.util.Scanner;
public class Solution {
private int[][] mat;
Scanner sc = new Scanner(System.in);
int n, m;
public Solution(int n, int m) {
this.n = n;
this.m = m;
mat = new int[n][m];
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
mat[i][j] = sc.nextInt();
for(int i = 0; i < n; i++) {
System.out.println();
for(int j = 0; j < m; j++)
System.out.print(mat[i][j] + "\t");
}
}
public void call() {
int sol = maxSortedMatrix(mat);
System.out.println("Matrix of order " + sol);
}
private int nearElements(int i, int j, int[][] mat, int[][] maxLongi) {
// basically recursively check surrounding elements. If they are exist and smaller than
// current element, we should consider it as the longest increasing sub sequence. However if we
// already check one element, the value corresponding to that index pair should no longer be zero,
// thus no need to recursively calculate that value again.
if (maxLongi[i][j] == 0) {
// have not been visited before, need recursive calculation
// have not recursively checking.
int length = 1;
// up
if (i - 1 > -1 && mat[i][j] > mat[i - 1][j]) {
length = Math.max(length, 1 + nearElements(i - 1, j, mat, maxLongi));
}
// down
if (i + 1 < mat.length && mat[i][j] > mat[i + 1][j]) {
length = Math.max(length, 1 + nearElements(i + 1, j, mat, maxLongi));
}
// left
if (j - 1 > -1 && mat[i][j] > mat[i][j - 1]) {
length = Math.max(length, 1 + nearElements(i, j - 1, mat, maxLongi));
}
// right
if (j + 1 < mat[0].length && mat[i][j] > mat[i][j + 1]) {
length = Math.max(length, 1 + nearElements(i, j + 1, mat, maxLongi));
}
maxLongi[i][j] = length; // setting maxLenTailing value here to avoid additional recurssively checking
return length;
}
return maxLongi[i][j];
}
private int maxSortedMatrix(int[][] mat) {
if (mat == null || mat.length == 0 || mat[0] == null || mat[0].length == 0) {
return 0;
}
int[][] maxLength = new int[n][m];
// store the max length of increasing subsequence that ending at i and j.
int max = 0;
// top left to bottom right
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
// scan every element in the matrix.
maxLength[i][j] = nearElements(i, j, mat, maxLength);
max = Math.max(max, maxLength[i][j]);
}
}
return max;
}
}
import java.util.Scanner;
公共类解决方案{
私有int[][]mat;
扫描仪sc=新的扫描仪(System.in);
int n,m;
公共解决方案(int n,int m){
这个,n=n;
这个,m=m;
mat=新整数[n][m];
对于(int i=0;i-1&&mat[i][j]>mat[i-1][j]){
长度=数学最大值(长度,1+近元素(i-1,j,mat,maxLongi));
}
//向下
如果(i+1mat[i+1][j]){
长度=数学最大值(长度,1+近元素(i+1,j,mat,maxLongi));
}
//左
if(j-1>-1&&mat[i][j]>mat[i][j-1]){
长度=数学最大值(长度,1+近元素(i,j-1,mat,maxLongi));
}
//对
如果(j+1mat[i][j+1]){
长度=数学最大值(长度,1+近元素(i,j+1,mat,maxLongi));
}
maxLongi[i][j]=length;//在此处设置maxLenTailing值以避免额外的递归检查
返回长度;
}
返回maxLongi[i][j];
}
专用int maxSortedMatrix(int[][]mat){
如果(mat==null | | mat.length==0 | | mat[0]==null | | mat[0]。length==0){
返回0;
}
int[]maxLength=新的int[n][m];
//存储以i和j结尾的递增子序列的最大长度。
int max=0;
//从左上到右下
对于(int i=0;i
问题是您的算法错误;你需要一个完全不同的
您的算法计算的是通过矩阵的最长递增路径的长度,即8
:
, , , , , 0
, , , 6, 2, 1
, , 20, 10, ,
, , 23, , ,
, , 24, , ,
它通过计算矩阵中每个元素在该元素处结束的最长递增路径的长度来实现这一点:
2, 1, 2, 1, 4, 1
1, 2, 5, 4, 3, 2
2, 3, 6, 5, 1, 3
3, 4, 7, 1, 2, 4
4, 5, 8, 2, 1, 2
然后选择该长度的最大值(即8
)
相反,您需要做的是为矩阵中的每个元素计算排序后的最大方形子矩阵的大小,该子矩阵的元素位于其右下角:
1, 1, 1, 1, 1, 1
1, 1, 2, 1, 1, 1
1, 2, 2, 1, 1, 1
1, 2, 3, 1, 1, 2
1, 2, 3, 1, 1, 1
然后选择该尺寸的最大值(即3
)
注意,与最长增长路径问题不同,这不需要递归和记忆;相反,这是一个纯粹的动态规划问题。您可以从矩阵的顶部到底部,从左到右,仅根据已经计算的子结果计算每个子结果。(我注意到你用[dynamic programming]标记了这个问题,所以我假设这是你的教授希望你做的。)正方形子矩阵的答案可能比一般矩形的答案更容易计算。在Python中,我们可以利用双重比较的小技巧(请参阅ruakh的答案进行一般性讨论):
a=[
[10, 1, 4, 1, 4, 0],
[ 1, 2,10, 6, 2, 1],
[ 6, 7,20,10, 1, 2],
[ 9,10,23, 0, 3, 5],
[10,11,24, 1, 0, 2]
]
m=[[1]*len(a[0])表示范围(0,len(a))内的i
对于范围(1,len(a))中的i:
对于范围(1,len(a[0])内的j:
如果[i-1][j-1]一个排序子矩阵的所有值都从左到右、从上到下(严格地?)增加,以符合可能的解决方案?它不应该返回6
?左上角的1、2、6、7、9、10。很抱歉,它应该返回3,这是排序最大的子矩阵的顺序:在第二行1、2、10;在第三排6、7、20和第四排9、10、23。一个排序的子矩阵需要所有元素按行和列按升序排列。因此,排序的子矩阵需要是一个正方形矩阵?我认为最后一个矩阵最右边列的顶部2
应该是1
。@㪞בקן:你说得很对。我有一只虫子;我正在测试结果[I][j]≥ {results[i-1][j],results[i][j-1],results[i-1][j-1]}而不是results[i][j]≥ {results[i-1][j],results[i][j-1]}≥ 结果[i-1][
1, 1, 1, 1, 1, 1
1, 1, 2, 1, 1, 1
1, 2, 2, 1, 1, 1
1, 2, 3, 1, 1, 2
1, 2, 3, 1, 1, 1