[JOYOI1466] 最美妙的矩阵

题目限制

时间限制 内存限制 评测方式 题目来源
1000ms 131072KiB 标准比较器 Local

题目背景

Candy的生日即将到来,飘飘乎居士希望找到一个最美妙的矩阵送个Candy作为礼物

题目描述

飘飘乎居士从Pink处得知最美妙的矩阵满足三个条件:首先,它的长和宽都必须和矩阵的边界平行(也就是不可以出现斜的矩阵);第二:子矩阵横竖都要满足单调递增(可以相等,也就是对于每一个最优子矩阵的元素都要满足a[i][j]>=a[i-1][j] and a[i][j]>=a[i][j-1],其中a[i][j]表示矩阵第i行第j列的数字);第三:最优矩阵是在满足上述两个条件中面积最大的矩阵。

输入格式

第一行,两个正整数n,m
        接下来n行,每行m个数字,构成一个n*m的矩阵

输出格式

一行,代表最优矩阵的面积

提示

最优子矩阵为
     2 4 4
     4 4 4
     该矩阵满足横竖都单调递增,并且是所有满足条件中面积最大的。其中矩阵长为3宽为2,面积为6,也就是最后的答案。
对于30%的数据  0<n m<=50
对于100%的数据 0<n m<=200
对于所有数据 a[i][j]<=20000000

样例数据

输入样例 #1 输出样例 #1
3 4

2 4 4 4

4 4 4 2

3 4 2 5

6


提交地址JOYOI1466


题解

我太菜了...

up[i][j] 表示(i, j)往上最多走多少

can[i][j][k]表示从第i行到第j行,第k列能否链接上第k-1列;

f[i][j][k]表示从i行到j行,到第k列时最大的面积


Code:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 int n, m;
 6 int a[210][210];
 7 int up[210][210];
 8 bool can[210][210][210];
 9 int f[210][210][210];
10 int ans;
11 
12 int main()
13 {
14     scanf("%d%d", &n, &m);
15     for (register int i = 1 ; i <= n ; i ++)
16         for (register int j = 1 ; j <= m ; j ++)
17             scanf("%d", &a[i][j]);
18     for (register int i = 1 ; i <= n ; i ++)
19     {
20         for (register int j = 1 ; j <= m ; j ++)
21         {
22             if (a[i][j] >= a[i-1][j]) up[i][j] = up[i-1][j] + 1;
23             else up[i][j] = 1;
24         }
25     }
26     
27     for (register int i = 1 ; i <= n ; i ++)
28     {
29         for (register int j = i ; j <= n ; j ++)
30         {
31             for (register int k = 1 ; k <= m ; k ++)
32             {
33                 if ((can[i][j-1][k] or j - i - 1 < 0) and up[j][k] >= j - i + 1 and a[j][k] >= a[j][k-1] and up[j][k-1] >= j - i + 1) can[i][j][k] = 1;    
34             }
35         }
36     }
37     
38     for (register int i = 1 ; i <= n ; i ++)
39     {
40         for (register int j = i ; j <= n ; j ++)
41         {
42             for (register int k = 1 ; k <= m ; k ++)
43             {
44                 if (can[i][j][k]) f[i][j][k] = f[i][j][k-1] + j - i + 1;
45                 else if (up[j][k] >= j - i + 1) f[i][j][k] = j - i + 1;
46                 ans = max(ans, f[i][j][k]);
47             }
48         }
49     }
50     cout << ans << endl;
51     
52     return 0;
53 }

猜你喜欢

转载自www.cnblogs.com/zZh-Brim/p/9154823.html
今日推荐