hihocoder1580 Matrix
题目链接:(vjudge)戳我
从今天开始不咕咕地填坑啦
考虑一般的求最大子矩阵和。。。我们一般都是DP,或者直接上悬线法递推。
下面附一个DP的代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 310
using namespace std;
int n,m,p,all,ans;
int a[MAXN][MAXN],dp[MAXN],minn[MAXN],sum[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
memset(minn,0x3f,sizeof(minn));
all=0,ans=-2147483647;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]),all+=a[i][j];
for(int l=1;l<=n;l++)
{
memset(sum,0,sizeof(sum));
for(int r=l;r<=n;r++)
{
for(int i=1;i<=m;i++)
{
sum[i]+=a[r][i];
if(l==r) minn[i]=a[r][i];
else minn[i]=min(minn[i],a[r][i]);
if(i==1) dp[i]=sum[i];
else dp[i]=max(sum[i],dp[i-1]+sum[i]);
ans=max(ans,dp[i]);
}
}
}
printf("%d\n",ans);
}
return 0;
}
然后这个题就是最大子矩阵和的变形。要求必须修改一个。
我们新开一个数组dp2[i]来记录第一维在\([l,r]\)范围内(这个做右端点是需要\(n^2\)枚举的),第二维计算到i的时候,修改了一个位置为p的最大子矩阵和。
因为要修改之后尽量大,所以我们转移的时候需要维护当前\(i\)这一列最小的矩形中最小的元素,那么带修改的自然就是减去这个最小值然后加上p了。
转移最大子矩形和的时候注意分类讨论,分一类为继承前一列,一类为自己新开一个。带修改的还需要分类讨论如果继承前一列,那个带修改的位置到底是在自己这一列还是在前面列中。
然后还有一点就是因为我们修改的这个位置不一定被选入到我们的最大子矩阵和的矩阵里,所以每个不修改的状态也要记录一遍。(当然要特判一下,所有数取满是非法情况要排除掉啦!)
然后每种情况都和ans取一个最大值。
具体看代码吧。代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 310
using namespace std;
int n,m,p,all,ans;
int a[MAXN][MAXN],dp1[MAXN],dp2[MAXN],minn[MAXN],sum[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
memset(a,0,sizeof(a));
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
memset(minn,0x3f,sizeof(minn));
all=0,ans=-2147483647;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]),all+=a[i][j];
for(int l=1;l<=n;l++)
{
memset(sum,0,sizeof(sum));
for(int r=l;r<=n;r++)
{
for(int i=1;i<=m;i++)
{
sum[i]+=a[r][i];
if(l==r) minn[i]=a[r][i];
else minn[i]=min(minn[i],a[r][i]);
if(i==1) dp1[i]=sum[i];
else dp1[i]=max(sum[i],dp1[i-1]+sum[i]);
if(i==1) dp2[i]=sum[i]-minn[i]+p;
else dp2[i]=max(dp2[i-1]+sum[i],max(dp1[i-1]+sum[i]-minn[i]+p,sum[i]-minn[i]+p));
if(dp1[i]!=all)
ans=max(ans,dp1[i]);
ans=max(ans,dp2[i]);
printf("l=%d r=%d i=%d ans=%d\n",l,r,i,ans);
}
}
}
printf("%d\n",ans);
}
return 0;
}
hihocoder1580 Matrix的更多相关文章
- angular2系列教程(十一)路由嵌套、路由生命周期、matrix URL notation
今天我们要讲的是ng2的路由的第二部分,包括路由嵌套.路由生命周期等知识点. 例子 例子仍然是上节课的例子:
- Pramp mock interview (4th practice): Matrix Spiral Print
March 16, 2016 Problem statement:Given a 2D array (matrix) named M, print all items of M in a spiral ...
- Atitit Data Matrix dm码的原理与特点
Atitit Data Matrix dm码的原理与特点 Datamatrix原名Datacode,由美国国际资料公司(International Data Matrix, 简称ID Matrix)于 ...
- Android笔记——Matrix
转自:http://www.cnblogs.com/qiengo/archive/2012/06/30/2570874.html#translate Matrix的数学原理 在Android中,如果你 ...
- 通过Matrix进行二维图形仿射变换
Affine Transformation是一种二维坐标到二维坐标之间的线性变换,保持二维图形的"平直性"和"平行性".仿射变换可以通过一系列的原子变换的复合来 ...
- [LeetCode] Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth ...
- [LeetCode] Longest Increasing Path in a Matrix 矩阵中的最长递增路径
Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...
- [LeetCode] Search a 2D Matrix II 搜索一个二维矩阵之二
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...
- [LeetCode] Search a 2D Matrix 搜索一个二维矩阵
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...
随机推荐
- a+b_1
题目截图: 思路: 直接输出即可. 代码如下: /* a+b */ #include <stdio.h> #include <string.h> #include <ma ...
- os.path.dirname( __ file __ ) 2018/6/2
os.path.dirname( __ file __ ) 2018/6/2 该测试脚本所在的位置:D:\第1层\第2层\第3层\第4层\第5层\test11.py import os #该文件所在位 ...
- 使用heap profiler进行内存占用分析
最近在项目中用到了google的heap profiler工具来分析内存占用,效果非常显著,因此在这里写一篇博客记录一下使用过程中遇到的一些问题. heap profiler依赖于tcmalloc,所 ...
- Linux实战教学笔记32:企业级Memcached服务应用实践
一, Memcached介绍 1.1 Memcached与常见同类软件对比 (1)Memcached是什么? Memcached是一个开源的,支持高性能,高并发的分布式内存缓存系统,由C语言编写,总共 ...
- telnet客户端模拟浏览器发送请求
telnet 客户端 telnet客户端能够发出请求去连接服务器(模拟浏览器) 使用telnet之前,需要开启telnet客户端 1.进入控制面板 2.进入程序和功能,选择打开或关闭windows功能 ...
- 由浅到深理解ROS(5)- launch启动文件的理解与编写
ROS提供了一个同时启动节点管理器(master)和多个节点的途径,即使用启动文件(launch file).事实上,在ROS功能包中,启动文件的使用是非常普遍的.任何包含两个或两个以上节点的系统都可 ...
- C#跨线程操作控件的最简单实现探究
随着程序复杂度的提高,程序不可避免会出现多个线程,此时就很可能存在跨线程操作控件的问题. 跨线程操作UI控件主要有三类方式: 1.禁止系统的线程间操作检查.(此法不建议使用) 2.使用Invoke(同 ...
- 阿里云WindowsServer2012安装IIS失败
本文地址:http://www.cnblogs.com/drfxiaoliuzi/p/6388417.html 首先,向微软官方论坛的大神致敬: https://social.technet.micr ...
- Oracle 11g 重建EM需要删除的对象
因为需求需要重建EM,重建时因为某些错误被迫停止,比如对象已存在.用户已经存在等,最终找出了创建必备的条件: 1.环境变量(Oracle和Grid在同一个用户下安装) ORACLE_HOME 要设为D ...
- 【Django】Django Debug Toolbar调试工具配置
正在发愁怎么调试Django,就遇到了Django Debug Toolbar这个利器. 先说遇到的问题: 网上也有教程,不过五花八门的,挨个尝试了一遍,也没有成功运行.最后终于找到问题所在: 从开发 ...