矩阵 matrix

Description

给出一个 n × m 的矩阵。请在其中选择至多 3 个互不相交的,大小恰为 k × k 的子矩阵,使得子矩阵的 权值和最大。

Input

第一行三个整数 n, m, k ( n, m ≤ 1500) 。

接下来 m 行,每行 n 个整数,描述矩阵。矩阵中的每个元素值都为非负整数,且不超过 500 。

Output

输出一行一个整数,描述答案。

Sample Input

9 9 3
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 8 8 8 8 8 1 1 1
1 8 8 8 8 8 1 1 1
1 8 8 8 8 8 1 1 1
1 1 1 1 8 8 8 1 1
1 1 1 1 1 1 8 8 8
1 1 1 1 1 1 9 9 9
1 1 1 1 1 1 9 9 9

Sample Output

208

解析

这道题似乎并不好写...

因为要使矩阵互不相交...

等等,

如果矩阵互不相交,那么肯定存在两条线,能把三个矩阵分开.

那么,就有六种情况(具体情况自己画一下吧毕竟我画的图丑陋到自己都看不下去),

于是我们可以用\(mp[i][j]\)表示以(\(i\),\(j\))为右下角的矩阵的和,

并用\(a[i][j]\),\(b[i][j]\),\(c[i][j]\),\(d[i][j]\),分别表示点(\(i\),\(j\))左上,右上,左下,右下区域中取一个\(k\)*\(k\)矩阵的最大值,

所以,只需要对于六种情况,分别枚举两条线,并更新答案就行了.

代码可能有点非常丑陋:

#include<bits/stdc++.h>
using namespace std; inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return f*sum;
} int n,m,k,ans=0;
int a[1501][1501],c[1501][1501];
int b[1501][1501],d[1501][1501];
int s[1501][1501],mp[1501][1501]; int main(){
n=read();m=read();k=read();
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++) a[i][j]=read();
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
for(int i=k;i<=m;i++)
for(int j=k;j<=n;j++) mp[i][j]=s[i][j]-s[i-k][j]-s[i][j-k]+s[i-k][j-k];
memset(a,0,sizeof(a));
for(int i=k;i<=m;i++)
for(int j=k;j<=n;j++) a[i][j]=max(mp[i][j],max(a[i-1][j],a[i][j-1]));
for(int i=k;i<=m;i++)
for(int j=k;j<=n;j++) b[i][j]=max(mp[i][j],max(b[i-1][j],b[i][j+1]));
for(int i=k;i<=m;i++)
for(int j=k;j<=n;j++) c[i][j]=max(mp[i][j],max(c[i+1][j],c[i][j-1]));
for(int i=k;i<=m;i++)
for(int j=k;j<=n;j++) d[i][j]=max(mp[i][j],max(d[i+1][j],d[i][j+1]));
for(int i=k;i<=m-k;i++)
for(int j=k;j<=n-k;j++) ans=max(ans,a[i][n]+c[i+k][j]+d[i+k][j+k]);
for(int i=k;i<=m-k;i++)
for(int j=k;j<=n-k;j++) ans=max(ans,c[i+k][n]+a[i][j]+b[i][j+k]);
for(int i=k;i<=m-k;i++)
for(int j=k;j<=n-k;j++) ans=max(ans,a[m][j]+b[i][j+k]+d[i+k][j+k]);
for(int i=k;i<=m-k;i++)
for(int j=k;j<=n-k;j++) ans=max(ans,b[m][j+k]+a[i][j]+c[i+k][j]);
for(int i=k;i<=m-k;i++)
for(int j=k+k;j<=n-k;j++) ans=max(ans,a[m][j-k]+mp[i][j]+b[m][j+k]);
for(int i=k+k;i<=m-k;i++)
for(int j=k;j<=n-k;j++) ans=max(ans,a[i-k][n]+mp[i][j]+c[i+k][n]);
printf("%d\n",ans);
return 0;
}

最新文章

  1. hdu4717The Moving Points(三分)
  2. Python如何进行cross validation training
  3. SQLServer 工具技巧
  4. 如何让你的SQL运行得更快
  5. [Openstack] Expecting an auth URL via either --os-auth-url or env[OS_AUTH_URL]
  6. 【原】手写一个promise
  7. react-router3.x hashHistory render两次的bug,及解决方案
  8. 关于bootstrap的一些想法
  9. kerberos简单介绍
  10. php(面向对象的基本介绍)
  11. percona-toolkit工具的使用
  12. Vuejs vm对象详解
  13. 最新jquery+easyui_api培训文档
  14. spring mvc请求过程
  15. 【LeetCode 235_二叉搜索树】Lowest Common Ancestor of a Binary Search Tree
  16. 7-掉馅饼(数组dp)
  17. 东莞裕同&amp;易普优APS项目启动啦!
  18. Freemarker-2.3.22 Demo - No02_绑定单个参数
  19. 【DP】【P2224】】【HNOI2001】产品加工
  20. c# 解析MP3文件

热门文章

  1. *【Python】【demo实验31】【练习实例】【使用turtle画小猪佩奇】
  2. #######【Python】【基础知识】【标准库】目录及学习规划 ######
  3. php 简单的 单例模式
  4. GET POST请求区别
  5. loj 3014「JOI 2019 Final」独特的城市
  6. Laravel 表单验证创建“表单请求”实现自定义请求类
  7. echart tooltip问题(鼠标放上去显示所有和显示当个)
  8. Java十进制转二进制
  9. ZooKeeper--动物管理员
  10. mybatis-03