题意:给一个矩阵,每个元素有正有负,求最大矩阵和。

解题:

(1)对原矩阵a用前缀和处理,处理变成矩阵sum,sum[i][j]表示从左上角为a[1][1]到右下角a[i][j]的全部元素和。

矩阵必须是连续起来的,两重循环列举所有的连续的行,再暴力循环每一列,相当于求最大连续子序列。

第i行到第j行的第k列压缩成一个数:sum[j][k]-sum[j][k-1]-sum[i-1][k]+sum[i-1][k-1];

图示:红色-黄色-蓝色+绿色

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<vector>
#include<iostream>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std; int a[105][105];
int sum[105][105];
int t,n,m; int part(int i,int j,int k)///第i行到第j行在第k列上的和
{
return sum[j][k]-sum[j][k-1]-sum[i-1][k]+sum[i-1][k-1];
} int main()
{
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
memset(sum,0,sizeof(sum));
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++)
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];///初始化矩阵前缀和 int maxx=-inf;
int x,y;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
x=part(i,j,1); ///初始值为第i行到第j行的第1列
y=x; ///存两个变量,备份,x拿来操作
for(int k=2;k<=m;k++)
{
if(x<0) ///x是从第1列进来的,如果当前的x小于0,越加越小, 不如不加,置为0再加相当于没加
x=0;
x+=part(i,j,k);///对于 加不加 第i行到第j行的第k列的部分和 ,y对每个x取最值,保存
y=max(x,y);
}
maxx=max(maxx,y);
}
}
printf("%d\n",maxx);
} return 0;
}

矩阵形式的前缀和

(2)对每一列前缀和处理,sum[i][j]表示a[1][j]到a[i][j]的和,双重暴力连续的行数,一重暴力列数,每个子列,第i行到第j行的第k列压缩成一个数:sum[j][k]-sum[i-1][k],相当于求最大连续子序列。

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<vector>
#include<iostream>
#include<set>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std; int a[105][105];
int sum[105][105];
int t,n,m; int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(a,0,sizeof(a));
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
sum[i][j]=sum[i-1][j]+a[i][j];///列的前缀和
}
}
int ans=-inf;
int now,maxx;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
now=sum[j][1]-sum[i-1][1];
maxx=now;
for(int k=2;k<=m;k++)
{
if(now<0)
now=0;
now+=sum[j][k]-sum[i-1][k];
maxx=max(now,maxx);
}
ans=max(maxx,ans);
}
}
printf("%d\n",ans);
}
return 0;
}

每列前缀和的形式

最新文章

  1. 腾讯开放平台 手机QQ登录 错误码:110406 解决办法
  2. Java操作excel
  3. Eclipse上GIT插件EGIT使用手册
  4. tp5页面输出时,搜索后跳转下一页的处理
  5. 【编程题目】有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;(需要回头仔细研究)
  6. vbox下Oracle Enterprise liunx5.4虚拟机安装10G RAC实验(四)
  7. linux下实时查看tomcat运行日志
  8. Centos是什么
  9. centos nginx 安装
  10. PHP命名空间概念解析
  11. Oracle中的AWR,全称为Automatic Workload Repository
  12. Spring框架基础(上)
  13. [译]RabbitMQ教程C#版 - 主题
  14. MySQL查询缓存总结
  15. IDEA中MAVEN项目有多个子目录,如何加载构建
  16. Android中处理崩溃闪退错误
  17. [转] 插件兼容CommonJS, AMD, CMD 和 原生 JS
  18. git 详细教程和常用操作指令
  19. 机器学习进阶-图像形态学操作-腐蚀操作 1.cv2.erode(进行腐蚀操作)
  20. Android 上SuperUser获取ROOT权限原理解析

热门文章

  1. DRF框架和Vue框架阅读目录
  2. Scala Collection Method
  3. 软件——解决Modelsim10.1d窗口不停弹出问题(一直弹窗)
  4. C#怎么判断字符是不是汉字 汉字和Unicode编码互相转换
  5. Ubuntu 18 Kubernetes集群的安装和部署 以及Helm的安装
  6. 带着canvas去流浪系列之八 碰撞【华为云技术分享】
  7. 另一个角度的redis--redis 可以看做是c/s架构的软件
  8. APS.NET MVC + EF (02)---深入理解ADO.NET Entity Framework
  9. robotframework-ride1.7.3.1更新安装
  10. Python进阶----多表查询(内连,左连,右连), 子查询(in,带比较运算符)