区间DP tyvj 1466 最美妙的矩阵

本文介绍了一种使用区间动态规划解决矩阵问题的方法。通过预处理和双重遍历技巧,实现了矩阵的有效划分,找到最大合法子矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tyvj 1466 最美妙的矩阵
一个链接:http://hzwer.com/1811.html
题目分析:
这是一道区间DP,但我一开始连暴力都想复杂了。(QWQ)结果连30分的暴力都没想到!!!
解法一:其实这道题的暴力应该还是蛮好想的!分别枚举两个端点(一个左上,一个右下)然后暴力扫一遍区间,看是否合法即可,然后记录最大值。
解法二:我们优化一下上述思路,我们先预处理一下。用u[i][j]记录第i行第j列的数往上单调递减的最大值,再用一个can[i][j][k]数组表示第i行到第j行中的第k列是否能和k-1列合在一起。然后就可以DP了,我们用f[i][j][k]表示从第i行到第j行中的第k列能够得到的最大面积。然后写一个if判断一下就好,具体看代码中说明。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int a[210][210],u[210][210],can[210][210][210],f[210][210][210];
int ans,n,m;
//a为原数组,用来存储输进来的值
//u[i][j]表示第i行第j列的往上单调递减的最大值
//can[i][j][k]表示第i行到第j行中的第k列能否满足要求
//f[i][j][k]表示第i行到第j行中的第k列的子矩阵的最大面积 
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i) 
        for(int j=1;j<=m;++j)
            scanf("%d",&a[i][j]);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            if(a[i][j]>=a[i-1][j]) u[i][j]=u[i-1][j]+1;
            else u[i][j]=1;
    for(int i=1;i<=n;++i)
        for(int j=i;j<=n;++j)
            for(int k=1;k<=m;++k)
                if((can[i][j-1][k]||j-1<i)&&j-i+1<=u[j][k]&&a[j][k]>=a[j][k-1]) 
     //(can[i][j-1][k]||j-1<i)这个条件是表示前一行可以满足要求或者当前j等于i时都可以
     //j-i+1<=u[j][k],在第j行第k列的位置上往上的单点递减区间长度得大于等于j-i+1
     //a[j][k]>=a[j][k-1],同行之间也要满足单调递增
                can[i][j][k]=1;
    for(int i=1;i<=n;++i)
        for(int j=i;j<=n;++j)
            for(int k=1;k<=m;++k) {
                if(can[i][j][k]) f[i][j][k]=f[i][j][k-1]+j-i+1;
                //如果满足条件,那么就更新,这里在原来数组的基础上加上j-i+1,
                //表示的是现在第i行到第j行的第k列可以加入进去
                else if(u[j][k]>=j-i+1) f[i][j][k]=j-i+1;
                //不能的话,如果u[j][k]>=j-i+1那就值赋值这一个单位宽度的区间面积
                ans=max(ans,f[i][j][k]);//去一个最大值
            }
    printf("%d",ans);
    return 0;   
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值