描述


http://www.luogu.org/problem/show?pid=1565

给出一个n*m的矩阵,求最大的且和值为正的子矩阵.

分析


很容易想到的是用前缀和维护,暴力枚举左上角和右下角,这样的复杂度是O(n^4)的.(虽然洛谷上这道题也能过)

一种神奇的方法:用前缀和记录每一行的前缀和.枚举的时候先枚举左右端点,然后分别算出左右端点之间每一行的和值,把一行看作一个单元(将一行压缩成一个点),求以行为单元的前缀和.然后前缀和相减可以得到子矩阵.而题目要求子矩阵的和值要为正,所以必须是值大的前缀和减值小的(相等不能减),所以把前缀和排个序.对于子矩阵t[i]-t[j](t是前缀和),t[i]必须大于t[j],而且t[i]代表的前缀和要尽可能"靠下",这样子矩阵才能尽可能大.所以我们排序后扫一遍前缀和,记录当前前缀和t[i]之前的(比t[i]大的)前缀和中最靠下的位置down,然后用down-t[i].id表示两个前缀和之差代表的子矩阵的高度(可能为负),记录最大高度h,最后乘以底边的长度(j-i+1)即可.

注意:

1.前缀和要加上0.

2.相同的不能相减,所以相同的前缀和把序号小的放在上面,这样减出来的就是负的.

 #include <bits/stdc++.h>
#define ll long long
using namespace std; const int maxn=+;
int n,m;
ll ans;
ll s[maxn][maxn]; struct node{
ll x,id;
node(){}
node(ll x,ll id):x(x),id(id){}
}t[maxn];
bool cmp(node x,node y){
if(x.x==y.x) return x.id<y.id;
return x.x>y.x;
}
void solve(){
for(int i=;i<=m;i++)
for(int j=i;j<=m;j++){
for(int k=;k<=n;k++) t[k]=node(t[k-].x+s[k][j]-s[k][i-],k);
t[]=node(,);
sort(t,t+n+,cmp);
ll down=t[].id,h=;
for(int k=;k<=n;k++){
h=max(h,down-t[k].id);
down=max(down,t[k].id);
}
ans=max(ans,h*(j-i+));
}
printf("%lld\n",ans);
}
void init(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
int t; scanf("%d",&t);
s[i][j]=s[i][j-]+t;
}
}
int main(){
init();
solve();
return ;
}

Luogu_1565_牛宫_(最大子矩阵)的更多相关文章

  1. BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心

    BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心 Description 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行 ...

  2. BZOJ_1084_[SCOI2005]_最大子矩阵_(动态规划)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1084 给出一个n*m的矩阵,其中m<=2,取k个子矩阵,求最大子矩阵和. 分析 1.m= ...

  3. codecomb 2093【牛宫】

    题目描述 Description Hzgd神牛准备给自己盖一座很华丽的宫殿.于是,他看中了一块N*M的矩形空地.空地中每个格子都有自己的海拔高度.胡张想让他的宫殿的平均海拔在海平面之上(假设海平面的高 ...

  4. 洛谷P1565牛宫

    传送门:题目点这里; 首先理解题目,就是要求给定矩阵中权值和不小于零的最大子矩阵,数据范围200也还不算棘手,暴力n^4的算法也可以水到50分.正解要用到单调栈配合二分和前缀和,复杂度n^3logn, ...

  5. 洛谷P1565 牛宫

    题目描述 AP 神牛准备给自己盖一座很华丽的宫殿.于是,他看中了一块N*M 的矩形空地. 空地中每个格子都有自己的海拔高度.AP 想让他的宫殿的平均海拔在海平面之上(假设 海平面的高度是0,平均数都会 ...

  6. 牛客_剑指offer_重建二叉树,再后续遍历_递归思想_分两端

       总结:    重建二叉树:其实就是根据前序和中序重建得到二叉树,得到后续,只要输出那边设置输出顺序即可 [编程题]重建二叉树 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的 ...

  7. AngularJs学习笔记--directive

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/directive Directive是教HTML玩一些新把戏的途径.在DOM编译期间,directiv ...

  8. Asp.net MVC + EF + Spring.Net 项目实践3

    Asp.net MVC + EF + Spring.Net 项目实践 这一篇要整合Model层和Repository层,提供一个统一的操作entity的接口层,代码下载地址(博客园上传不了10M以上的 ...

  9. Asp.net MVC + EF + Spring.Net 项目实践(三)

    这一篇要整合Model层和Repository层,提供一个统一的操作entity的接口层,代码下载地址(博客园上传不了10M以上的文件,所以用了百度):http://pan.baidu.com/s/1 ...

随机推荐

  1. css3 animation实现逐帧动画

    css3里面的animation属性非常强大,但是自己用的比较少,最近有次面试就刚好被问到了,趁现在有时间就对animation做一个小总结.同时实现一个逐帧动画的demo作为练习 animation ...

  2. Java JDK1.5、1.6、1.7新特性整理(转)

    原文链接:http://www.cnblogs.com/tony-yang-flutter/p/3503935.html 一.Java JDK1.5的新特性 1.泛型: List<String& ...

  3. SQL SERVER删除列,报错."由于一个或多个对象访问此列,ALTER TABLE DROP COLUMN ... 失败"

    队友给我修改数据的语句.总是执行失败.很纳闷. 如下图: 仔细看了下这个列,并没有什么特殊.如下图: 但其确实有个约束: 'DF__HIS_DRUG___ALL_I__04E4BC85' . 为什么有 ...

  4. hibernate的dao操作不能提交到数据库问题的解决

    刚学的时候总是各种错误,解决方法也无厘头的很 将UserDAO里面的的save方法修改try { getSession().save(transientInstance); log.debug(&qu ...

  5. 简单模拟Hibernate的主要功能实现

    在学习期间接触到Hibernate框架,这是一款非常优秀的O/R映射框架,大大简化了在开发web项目过程中对数据库的操作.这里就简单模拟其底层的实现. /*******代码部分,及其主要注解***** ...

  6. linux中 ECShop的文件不能写

    解决办法: 1.开放权限 使用命令:chmod -R 777 文件路径 2.关闭SELinux 使用命令:setenforce 0

  7. poj 3783 Balls 动态规划 100层楼投鸡蛋问题

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098409.html 题目链接:poj 3783 Balls 动态规划 100层楼投鸡蛋问题 ...

  8. js之replace实现简单模板替换引擎

    eg: var app={}; app.tempEngine= (function () {  var pattern = /\{(\w*[:]*[=]*\w+)\}(?!})/g;  return ...

  9. ContextMenuOpening 事件

    ContextMenuOpening事件,不能在将要触发的目标ContextMenu中触发,只能包含 这个ContextMenu的父控件中触发该事件. 在ListView中,希望控制右键弹出菜单时,可 ...

  10. call(this)引起的对闭包的重新理解

    call(this)引起的对闭包的重新理解.md 变量的作用域 全局变量局部变量 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. 函数外部无法读取函数内的局部变量. 函数内部 ...