题意:
给出一个N*M的矩阵A,计算矩阵B,满足B[i][j]=min{ A[x][y]:(y>=j) and ( x>=i+j-y )},N,M∈[1,1000],每个元素绝对值小于32000。
分析:
首先我们即求一个切掉一块的矩形中的最小值。
记录C[i][j]为min{A[k][j](i<=k<=n)}。
那么B[i][j]=min{C[i][j],B[ni][nj]},当i>1时ni=i-1,否则ni=1;当j<m时nj=j+1,否则nj=m,动归一下即可。
给出一个N*M的矩阵A,计算矩阵B,满足B[i][j]=min{ A[x][y]:(y>=j) and ( x>=i+j-y )},N,M∈[1,1000],每个元素绝对值小于32000。
分析:
首先我们即求一个切掉一块的矩形中的最小值。
记录C[i][j]为min{A[k][j](i<=k<=n)}。
那么B[i][j]=min{C[i][j],B[ni][nj]},当i>1时ni=i-1,否则ni=1;当j<m时nj=j+1,否则nj=m,动归一下即可。
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1009, INF = 32700;
int n, m;
short A[MAXN][MAXN];
short B[MAXN][MAXN];
short dp(int i, int j)
{
if(B[i][j] != -INF) return B[i][j];
if(j == m) return B[i][j] = A[i][j];
int ti = i, tj = j;
if(ti > 1) ti--;
if(tj < m) tj++;
return B[i][j] = min(A[i][j], dp(ti, tj));
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
{
scanf("%hd", &A[i][j]);
B[i][j] = -INF;
}
for(int i = n-1; i >= 1; --i)
for(int j = 1; j <= m; ++j)
if(A[i][j] > A[i+1][j])
A[i][j] = A[i+1][j];
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
dp(i, j);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j < m; ++j)
printf("%hd ", B[i][j]);
printf("%hd\n", B[i][m]);
}
return 0;
}