bzoj1177&p3625 [APIO2009]采油区域p[大力讨论]
给定矩形,从中选出三个边长K的正方形互不重叠,使得覆盖到的数总和最大。
想的时候往dp上钻去了。。结果一开始想了一个错的dp,像这样
/**************************************************************
Problem: 1177
User: stealthassassin
Language: C++
Result: Wrong_Answer
****************************************************************/ #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define ddbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T _max(T A,T B,T C){return _max(A,_max(B,C));}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+;
ll sum[N][N];
int f[N][N][],n,m,A;
inline int get_sum(int xa,int ya,int xb,int yb){return sum[xb][yb]-sum[xa][yb]-sum[xb][ya]+sum[xa][ya];} int main(){//freopen("test.in","r",stdin);freopen("test.out","w",stdout);
read(n),read(m),read(A);
for(register int i=;i<=n;++i)for(register int j=;j<=m;++j)sum[i][j]=read(sum[i][j])+sum[i-][j]+sum[i][j-]-sum[i-][j-];
for(register int k=;k<=;++k)for(register int i=A;i<=n;++i)for(register int j=A;j<=m;++j)
f[i][j][k]=_max(f[i-][j][k],f[i][j-][k],_max(f[i-A][j][k-],f[i][j-A][k-])+get_sum(i-A,j-A,i,j));//ddbg(i,j),ddbg(k,f[i][j][k]);
printf("%d\n",f[n][m][]);
return ;
}
结果WA。还发现竟然骗了40pts。很快就发现dp推得有问题。明显没有办法用简单的dp状态来表示,想了一会复杂的dp方法,想不出来,然后就觉得这题DP不可做。然后陷入了僵局,尝试各种乱七八糟的做法却无果。
之后翻题解才发现,你3个正方形,个数那么少,用不了dp,那明摆着就是让你研究他们相对位置关系嘛。。
所以下面大力讨论一下,最大答案就有了这几种可能分布情况(红线表示区块的分界):
所以只要对每种情况都找一下最大总和,具体就是枚举边界线,3456四种分别二重横竖枚举$O(nm)$,每个区块里找最大值矩形,这个可以用前缀和加递推提前预处理,看code。
12就枚举一条边界线,然后中间那块不妨是k宽度的也没问题,在k宽度中找一个最大的,再配上边上两块最大的。
所以这题代码真的是写的恶心。。。而且BZOJ数据有锅,用快读还超时。。做了近4小时,心态有点崩溃。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define ddbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define per(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T _max(T A,T B,T C){return _max(A,_max(B,C));}
//namespace io
//{
// const int SIZE = (1 << 21) + 1;
// char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
// #define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
// inline void flush (){fwrite (obuf, 1, oS - obuf, stdout);oS = obuf;}
// inline void putc (char x){*oS ++ = x;if (oS == oT) flush ();}
// template <class I>
// inline void read(I &x) {for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
// for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;}
// template <class I>
// inline void print (I x){
// if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;while(x) qu[++ qr] = x % 10 + '0', x /= 10;while (qr) putc (qu[qr--]);}
// struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
//}
//using io::read;
//using io::putc;
//using io::print;
const int N=+;
int a[N][N],zs[N][N],ys[N][N],zx[N][N],yx[N][N],ans;
int n,m,k; int main(){//freopen("tmp.in","r",stdin);freopen("tmp.out","w",stdout);
cin>>n>>m>>k;
rep(i,,n)rep(j,,m)scanf("%d",&a[i][j]),a[i][j]+=a[i][j-];
rep(i,,n)rep(j,,m)a[i][j]+=a[i-][j];
per(i,n,k)per(j,m,k)a[i][j]=a[i][j]-a[i-k][j]-a[i][j-k]+a[i-k][j-k];
rep(i,k,n)rep(j,k,m)zs[i][j]=max(a[i][j],max(zs[i-][j],zs[i][j-]));
rep(i,k,n)per(j,m,k)ys[i][j]=max(a[i][j],max(ys[i-][j],ys[i][j+]));
per(i,n,k)rep(j,k,m)zx[i][j]=max(a[i][j],max(zx[i+][j],zx[i][j-]));
per(i,n,k)per(j,m,k)yx[i][j]=max(a[i][j],max(yx[i+][j],yx[i][j+]));
rep(i,k,n-*k)rep(j,k,m)ans=max(ans,zs[i][m]+a[i+k][j]+yx[i+k*][k]);
rep(i,k,m-*k)rep(j,k,n)ans=max(ans,zs[n][i]+a[j][i+k]+yx[k][i+k*]);
rep(i,k,n-k)rep(j,k,m-k)ans=max(ans,zs[i][j]+ys[i][j+k]+yx[i+k][k]);
rep(i,k,n-k)rep(j,k,m-k)ans=max(ans,zx[i+k][j]+yx[i+k][j+k]+zs[i][m]);
rep(i,k,m-k)rep(j,k,n-k)ans=max(ans,zs[j][i]+zx[j+k][i]+yx[k][i+k]);
rep(i,k,m-k)rep(j,k,n-k)ans=max(ans,ys[j][i+k]+yx[j+k][i+k]+zs[n][i]);
printf("%d\n",ans);
return ;
}
bzoj1177&p3625 [APIO2009]采油区域p[大力讨论]的更多相关文章
- 洛谷P3625 - [APIO2009]采油区域
Portal Description 给出一个\(n\times m(n,m\leq1500)\)的矩阵,从中选出\(3\)个互不相交的\(k\times k\)方阵,使得被选出的数的和最大. Sol ...
- [SOJ #686]抢救(2019-11-7考试)/[洛谷P3625][APIO2009]采油区域
题目大意 有一个\(n\times m\)的网格,\((x,y)\)权值为\(a_{x,y}\),要求从中选取三个不相交的\(k\times k\)的正方形使得它们权值最大.\(n,m,k\leqsl ...
- [P3625][APIO2009]采油区域 (前缀和)
这道题用二维前缀和可以做 难度还不算高,细节需要注意 调试了很久…… 主要是细节太多了 #include<bits/stdc++.h> using namespace std; #defi ...
- 洛谷 P3625 [APIO2009]采油区域【枚举】
参考:https://blog.csdn.net/FAreStorm/article/details/49200383 没有技术含量但是难想难写,枚举情况图详见参考blog懒得画了 bzoj蜜汁TTT ...
- [APIO2009]采油区域
题目描述 Siruseri 政府决定将石油资源丰富的 Navalur 省的土地拍卖给私人承包商以 建立油井.被拍卖的整块土地为一个矩形区域,被划分为 M×N 个小块. Siruseri 地质调查局有关 ...
- Luogu 3625 [APIO2009]采油区域
想了很久的dp,看了一眼题解之后感觉自己被安排了. 发现从一个矩形中选择三个不相交的正方形一共只有六种取法. 那么我们可以处理出四个值: $f_{i, j}$分别表示以$(i, j)$为右下角,左下角 ...
- Java实现 蓝桥杯VIP 算法训练 采油区域
算法训练 采油区域 时间限制:2.0s 内存限制:512.0MB 提交此题 查看参考代码 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整 ...
- Noip 训练指南
目录 Noip 训练指南 图论 数据结构 位运算 期望 题解 Noip 训练指南 目前完成 \(4 / 72\) 图论 [ ] 跳楼机 [ ] 墨墨的等式 [ ] 最优贸易 [ ] 泥泞的道路 [ ] ...
- [BZOJ1177][Apio2009]Oil
[BZOJ1177][Apio2009]Oil 试题描述 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整块土地为一个矩形区域,被划分为M ...
随机推荐
- jquery列表自动加载更多
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- POJ 2155 Matrix(二维树状数组,绝对具体)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20599 Accepted: 7673 Descripti ...
- C语言的##
比如说我定义一个宏:#define DECLARE_DYNAMIC(class_name) \public:static CRuntimeClass class##class_name; \virtu ...
- SpringBoot启动流程分析(三):SpringApplication的run方法之prepareContext()方法
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- matlab2017b linux版分享
链接:https://pan.baidu.com/s/1smrTkFN 密码:cvb3 下载后请点关注并点赞,谢谢支持.
- 常用string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- php nginx超时出错
执行PHP操作大文件insert mysql数据库时,出现这个错误提示 The page you are looking for is temporarily unavailable.Please t ...
- Linux下Kafka单机安装配置方法
Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息系统的功能,但具有自己独特的设计.这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统术语: •Kafka将消息以topi ...
- maven新建项目报错
创建了一个maven项目,报错 Errors occurred during the build. Errors running builder 'Maven Project Builder' on ...
- excel十几万行数据快速导入数据库研究(转,下面那个方法看看还是可以的)
先贴原来的导入数据代码: 8 import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "www.setting ...