HihoCoder 1634 Puzzle Game(最大子矩阵和)题解
题意:给一个n*m的矩阵,你只能选择一个格子把这个格子的数换成p(也可以一个都不换),问最大子矩阵和最小可能是多少?
思路:

思路就是上面这个思路,这里简单讲一下怎么n^3求最大子矩阵和:枚举两行(或者两列),然后把每一列之和看做一个数字,这样二维就变成了一维,我们可以直接求最大子串和的方法。初始一个ret为0,然后从左往右加,如果ret<0,那么把ret初始化0,负数作为初始值肯定比重新开始小,然后找出ret的最大值就是最大子矩阵和。
代码:
#include<cstdio>
#include<cstring>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
int num[maxn][maxn], sum[maxn][maxn];
int up[maxn], down[maxn], left[maxn], right[maxn];
int n, m, p, xx1, yy1, xx2, yy2;
int min(int x, int y){
return x < y? x : y;
}
int max(int x, int y){
return x > y? x : y;
}
int mat(int x1, int y1, int x2, int y2){
return sum[x2][y2] - sum[x1 - ][y2] - sum[x2][y1 - ] + sum[x1 - ][y1 - ];
}
int main(){
while(~scanf("%d%d%d", &n, &m, &p)){
memset(sum, , sizeof(sum));
for(int i = ; i <= n; i++){
for(int j = ; j <= m; j++){
scanf("%d", &num[i][j]);
sum[i][j] = num[i][j] + sum[i - ][j] + sum[i][j - ] - sum[i - ][j - ];
}
} //上下左右四个矩阵预处理
memset(up, -INF ,sizeof(up));
for(int i = ; i <= n; i++){
int tmp = -INF;
for(int j = ; j <= i; j++){
int ret = ;
for(int k = ; k <= m; k++){
ret += mat(j, k, i, k);
tmp = max(tmp, ret);
if(ret < ) ret = ;
}
}
up[i] = max(up[i - ], tmp);
}
memset(down, -INF, sizeof(down));
for(int i = n; i >= ; i--){
int tmp = -INF;
for(int j = i; j <= n; j++){
int ret = ;
for(int k = ; k <= m; k++){
ret += mat(i, k, j, k);
tmp = max(tmp, ret);
if(ret < ) ret = ;
}
}
down[i] = max(down[i + ], tmp);
}
memset(left, -INF, sizeof(left));
for(int i = ; i <= m; i++){
int tmp = -INF;
for(int j = ; j <= i; j++){
int ret = ;
for(int k = ; k <= n; k++){
ret += mat(k, j, k, i);
tmp = max(ret, tmp);
if(ret < ) ret = ;
}
}
left[i] = max(left[i - ], tmp);
}
memset(right, -INF, sizeof(right));
for(int i = m; i >= ; i--){
int tmp = -INF;
for(int j = i; j <= m; j++){
int ret = ;
for(int k = ; k <= n; k++){
ret += mat(k, i, k, j);
tmp = max(ret, tmp);
if(ret < ) ret = ;
}
}
right[i] = max(right[i + ], tmp);
} int Max = -INF;
for(int i = ; i <= n; i++){
for(int j = ; j <= i; j++){
int ret = , start = ;;
for(int k = ; k <= m; k++){
ret += mat(j, k, i, k);
if(ret > Max){
Max = ret;
xx1 = j, yy1 = start, xx2 = i, yy2 = k;
}
if(ret < ) ret = , start = k + ;
}
}
}
int ans = Max;
for(int i = xx1; i <= xx2; i++){
for(int j = yy1; j <= yy2; j++){
if(p > num[i][j]) continue;
ans = min(ans , max(Max - num[i][j] + p, max(up[i - ], max(down[i + ], max(left[j - ], right[j + ])))));
}
}
printf("%d\n", ans);
}
return ;
}
HihoCoder 1634 Puzzle Game(最大子矩阵和)题解的更多相关文章
- Hihocoder 1634 Puzzle Game(2017 ACM-ICPC 北京区域赛 H题,枚举 + 最大子矩阵变形)
题目链接 2017 Beijing Problem H 题意 给定一个$n * m$的矩阵,现在可以把矩阵中的任意一个数换成$p$,求替换之后最大子矩阵的最小值. 首先想一想暴力的方法,枚举矩阵中 ...
- Puzzle Game HihoCoder - 1634
题目链接:https://cn.vjudge.net/problem/HihoCoder-1634 题目意思:可以让矩阵里的某一个数变成p,或者不修改.求最大子矩阵最小,输出最小值. 思路:请看下图 ...
- ZOJ 1602 Multiplication Puzzle(区间DP)题解
题意:n个数字的串,每取出一个数字的代价为该数字和左右的乘积(1.n不能取),问最小代价 思路:dp[i][j]表示把i~j取到只剩 i.j 的最小代价. 代码: #include<set> ...
- hihocoder #1301 : 筑地市场 数位dp+二分
题目链接: http://hihocoder.com/problemset/problem/1301?sid=804672 题解: 二分答案,每次判断用数位dp做. #include<iostr ...
- hihocoder #1224 : 赛车 dfs
#1224 : 赛车 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/1224 ...
- 牛客网暑期ACM多校训练营(第二场)carpet
传送门:carpet 题意 有一个n*m的地毯,aij表示地毯每格的元素,bij表示地毯每格的价格,要求选取一块价格最大值最小的地毯,并且这块地毯无限铺开之后,原地毯是其子矩阵. 题解 先找到这个矩阵 ...
- NOI题库 1768最大子矩阵 题解
NOI题库 1768最大子矩阵 题解 总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大 ...
- 【题解】Puzzle [Uva1399]
[题解]Puzzle [Uva1399] 传送门:\(\text{Puzzle [Uva1399]}\) [题目描述] 给定 \(m\) 和 \(n\),表示有 \(m\) 种不同的字符(大写字母\( ...
- hihoCoder [Offer收割]编程练习赛3 D子矩阵求和
子矩阵求和 http://hihocoder.com/discuss/question/3005 声明一下: n是和x一起的,m是和y一起的 x是横着的,y是纵着的,x往右为正,y往下为正 (非常反常 ...
随机推荐
- linux中使用另一用户打开拥有图形界面的程序
在archlinux中使用oracle用户执行oui无法显示图形界面的问题.结果没解决,后来发现执行 xhost +si:localuser:oracle, 然后再使用oracle用户执行oui即可. ...
- 关于kingoroot这款软件
弃了饱受诟病的kingroot系列的软件,又出现了一款名为kingoroot的软件. 大约一年之前用过kingoroot的apk版,成功为我的手机root了,而且其行为也并不是那么流氓,所以当时对其很 ...
- [8]windows内核情景分析--窗口消息
消息与钩子 众所周知,Windows系统是消息驱动的,现在我们就来看Windows的消息机制. 早期的Windows的窗口图形机制是在用户空间实现的,后来为了提高图形处理效率,将这部分移入内核空间,在 ...
- 学习笔记<1>技术体系结构
Android的系统架构采用了分层架构的思想,如上图所示.从上层到底层共包括四层,分别是 1.应用程序程序层 2.应用框架层 3.系统库和Android运行时 4.Linux内核. 每 ...
- python windows 下pip easy_install 使用错误的问题
最近电脑重装了系统,又重新安装python .在官网下载了安装包后电脑成功安装了,但使用pip命令时出现以下错误 Fatal error in launcher: Unable to create p ...
- html5-盒子模型
/*div{background: green;width: 60%;padding-top: 10px;padding-right: 20px;padding-bottom: 30px;paddin ...
- 三角形垂点坐标js算法(三点定圆求圆心)
已知平面三点坐标A(x1, y1).B(x2, y2).C(x3, y3),三点定圆也就是三角形的中垂线交点, //平面三点定位算法 function locate(x1, y1, x2, y2, x ...
- ptrace线程
在ptrace时使用waitpid(-1, &status, 0);无法正常trace 修改为waitpid(-1, &status, __WALL);即可 原因是:
- bzoj1606
题目链接 反着循环就是每个东西只能选一次 #include<iostream> #include<cstdio> #include<cstdlib> #includ ...
- GoldenGate 12.3 MA架构介绍系列(4)–Restful API介绍
OGG 12.3 MA中最大的变化就是使用了restful api,在前面介绍的各个服务模块,其实就是引用restful api开发而来,这些API同时也提供对外的集成接口,详细接口可参考: http ...