折型最大 c++

14 篇文章 0 订阅
3 篇文章 0 订阅

折型最大

题目描述

折型在日常生活中随处可见,比如闪电符号“ ” ,显示器的四个角等等;折型大致可以
分为四种类型(“┌”,“┐”,“└”,“┘”)。笨笨只对“┘”这种折型特别感兴趣(萝卜青菜,
各有所爱),笨笨想在一个二维矩阵中求“┘”这种数字加和最大的折型,具体规定如下描述:
对于一个 N 行*M 列的矩阵,一个折型区域必须满足:
1、它的形状为“┘”(不能是“└”,“┌”,或“┐”);
2、它的宽度为 1;
3、它的横向长度和纵向长度都必须大于 1 且连续,不能等于 1(即不能退化为一条线或一
个点);
现给出这个二维矩阵,求其中数字和最大的这种折型区域。

输入

第一行为 N,M,中间用一个空格隔开, N 表示矩阵的行数, M 表示矩阵的列数;
接下来是 N 行,每行 M 个整数,每 2 个整数之间用 1 个空格隔开,每个整数 A[i,j]在[-100,100];

输出

一行一个整数,即满足题目要求的折型区域的最大数字和。

提示

t

【样例解释】 如右图所示,符合要求的折型区域数字和最大

【数据规模】
对于 30%的数据: 2≤M,N≤100;
对于 60%的数据: 2≤M,N≤500;
对于 100%的数据: 2≤M,N≤1,000; -100≤A[i,j]≤100;## 样例

#1

输入数据

4 4
-2 5 0 3
-1 1 0 -3
3 -2 -4 -6
-3 5 -5 5

输出数据

7

分析

这题基本上可以分成两个做法,一个是60分的做法,一个是100分的做法

60分做法

可以遍历上面中间和左边的三个点求出最值,但显然时间复杂度跟高,到了O(n^3)只能得60分。

满分做法

先定义两个数组f1和f2都是二维的,然后第一个数组表示[i][j]这个位置向上连和最大的方案的和,
在这里插入图片描述

第二个数组表示[i][j]这个位置向左连和最大的方案的和,
在这里插入图片描述
最后再将两个数组合起来,这道题就做完了。

需要注意的几个点:

1.f1 和 f2两个数组每一个数必须至少是两个数的和(要不可能输出的方案是一个横着的线或者竖着的线)
2.最后遍历时第一行和第一列不能遍历(要不也可能变成一条线)

上ac代码

#include<iostream>
using namespace std;
int f1[1010][1010],f2[1010][1010],a[1010][1010],n,m;
int main(){
    cin >> n >> m;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++){
        cin >> a[i][j];
        f1[i][j] = -1000000;
        f2[i][j] = -1000000;
    }
     
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            f1[i][j] = max(f1[i][j-1]+a[i][j],a[i][j]+a[i][j-1]);
            f2[i][j] = max(f2[i-1][j]+a[i][j],a[i][j]+a[i-1][j]);
//          cout << f2[i][j] << " ";
        }
//      cout << endl;
    }
    int maxn = -1000000;
//  cout << maxn << endl;
    for(int i=2;i<=n;i++)for(int j=2;j<=m;j++){
//      maxn = max(maxn,f1[i][j]+f2[i][j]);
        if(f1[i][j]+f2[i][j]-a[i][j]>maxn){
            maxn = f1[i][j]+f2[i][j]-a[i][j];
//          cout << maxn <<" "<<i <<" "<<j<<" "<< f1[i][j]<<" "<<f2[i][j]<< endl;       
        }
    }
    cout << maxn << endl;
}/**************************************************************
    Language: C++
    Result: 正确100
    Time:212 ms
    Memory:13668 kb
****************************************************************/

感谢您的观看!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值