题目描述:
解题思路:
这道题目是求最长上升序列的变形题,在求最长上升序列的时候,我们定义dp数组来存储每个位置上对应的符合条件的状态量,遍历,当前面有小于自身的数的时候,dp就更新和自身以及小于自身数+1取最大值,这里对应的思想就是,如果前面出现了比某个数大的数,这个数就可以加到前面数字后面,构成新长度的序列.
这道题我们把矩阵每一行看作一个数,在更新dp状态时候的判断就变成了判断一整行的元素情况了.因为这道题是下降矩阵,所以就是当前面行所有元素都比下面行元素大的时候,才去更新dp的状态,否则,一旦前面有一个小于或者等于下面行的数,我们就return false.
参考代码:
public class d_2518 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
long[][] arr=new long[n][m];
int[] dp=new int[305];
int max=1;
Arrays.fill(dp,1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
arr[i][j]=sc.nextLong();
}
}
for (int i = 1; i <n; i++) {
for (int j = 0; j < i; j++) {
if(cam2(i,j,m,arr)) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
max=Math.max(max,dp[i]);
}
//最后输出最少消去的行数就是:总行数-最长连续递减行数
System.out.println(n-max);
}
private static boolean cam2(int i, int j,int m,long[][] arr) {
//这里很容易弄错(要搞清楚找的是递减的序列)
//要找下降矩阵,就是看前面有几个比他大的数,
for (int k = 0; k < m; k++) {
//如果前面这个数比它小了,二维数组一行一但出现比下一行小的,就无法构成递减序列
if(arr[j][k]<=arr[i][k])
return false;
}
//说明前面一行都比下一行的数大,整个行和下一行可以构成递减序列,就可以在结果上+1,更新dp数组的状态
return true;
}