LOJ#2668 书法家
题意:要在一张网格纸上画出NOI图形,使得所占格子的权值和最大。
解:暴力DP即可...
从左往右,每个字母都可以被划分成三块,且每块都可用上下两维来表示。
于是一块一块的DP。考虑如何O(1)转移。显然只有N的中间那一块不好转移,别的都是直接转移。
N的三块的两个连接处之间,可以枚举必须持平的那个端点,另一个用前缀最值。
N第二块内部,考虑枚举后一个矩形的上边界,逐步扩展下边界。此时发现每扩展一步,可能的决策集合会增加:左边一格,下边界为刚扩展的那一格,上边界在枚举的上边界以上的所有状态。
于是对于每个下边界,预处理出上边界从上到下的一个前缀最值,加到决策集合里取max即可。
#include <bits/stdc++.h> const int INF = 0x3f3f3f3f; #define g f[FLAG]
#define h f[FLAG ^ 1] int f[][][][], FLAG, n, m;
int s[][], p[], temp[][]; inline int getSum(int i, int l, int r) {
if(l > r) return ;
return s[r][i] - s[l - ][i];
} inline void out() {
for(int i = ; i <= m; i++) {
for(int up = ; up <= n; up++) {
for(int down = up; down <= n; down++) {
printf("%d ", g[i][up][down]);
}
}
puts("");
}
puts("");
return;
} inline void outp() {
printf("p : ");
for(int i = ; i <= m; i++) {
printf("%d ", p[i]);
}
puts("");
puts("");
return;
} int main() {
//printf("%d \n", sizeof(f) / 1048576); scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
scanf("%d", &s[i][j]);
s[i][j] += s[i - ][j];
}
} FLAG = ; /// N 1
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = std::max(, g[i - ][up][down]) + getSum(i, up, down);
}
}
} //out(); FLAG ^= ; /// N 1.5
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n; up++) {
int large = -INF;
for(int down = n - ; down >= up; down--) {
large = std::max(large, h[i - ][up][down + ]);
g[i][up][down] = large + getSum(i, up, down);
}
}
} //out(); FLAG ^= ; /// N 2
//memset(g, ~0x3f, sizeof(g));
memcpy(g, h, sizeof(h));
for(int i = ; i <= m; i++) {
memset(temp, ~0x3f, sizeof(temp));
for(int down = ; down <= n; down++) {
for(int up = ; up <= down; up++) {
temp[down][up] = std::max(temp[down][up - ], std::max(g[i - ][up][down], h[i - ][up][down]));
}
}
for(int up = ; up <= n; up++) {
int large = temp[up - ][up - ];
for(int down = up; down <= n; down++) {
large = std::max(large, temp[down][up]);
g[i][up][down] = std::max(large + getSum(i, up, down), h[i][up][down]);
}
}
} //out(); FLAG ^= ; /// N 2.5
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int down = ; down <= n; down++) {
int large = -INF;
for(int up = down - ; up >= ; up--) {
large = std::max(large, h[i - ][up + ][down]);
g[i][up][down] = large + getSum(i, up, down);
}
}
} //out(); FLAG ^= ; /// N 3
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = std::max(h[i][up][down], g[i - ][up][down] + getSum(i, up, down));
}
}
} //out(); /// get p : max of g
memset(p, ~0x3f, sizeof(p));
for(int i = ; i <= m; i++) {
p[i] = p[i - ];
for(int up = ; up <= n; up++) {
for(int down = ; down <= n; down++) {
p[i] = std::max(p[i], g[i][up][down]);
}
}
} //outp(); //out(); //printf(" O 1 \n"); FLAG ^= ; /// O 1
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n - ; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = p[i - ] + getSum(i, up, down);
}
}
} //out(); //printf(" O 2 \n"); FLAG ^= ; /// O 2
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n - ; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = std::max(h[i - ][up][down], g[i - ][up][down]) + getSum(i, up, up) + getSum(i, down, down);
}
}
} //out(); FLAG ^= ; /// O 3
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n - ; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = h[i - ][up][down] + getSum(i, up, down);
}
}
} //out(); /// get p : max of g
memset(p, ~0x3f, sizeof(p));
for(int i = ; i <= m; i++) {
p[i] = p[i - ];
for(int up = ; up < n - ; up++) {
for(int down = up + ; down <= n; down++) {
p[i] = std::max(p[i], g[i][up][down]);
}
}
} //outp(); //out(); FLAG ^= ; /// I 1
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n - ; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = std::max(p[i - ], g[i - ][up][down]) + getSum(i, up, up) + getSum(i, down, down);
}
}
} //out(); FLAG ^= ; /// I 2
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n - ; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = std::max(g[i - ][up][down], h[i - ][up][down]) + getSum(i, up, down);
}
}
} //out();
int ans = -INF; FLAG ^= ; /// I 3
memset(g, ~0x3f, sizeof(g));
for(int i = ; i <= m; i++) {
for(int up = ; up < n - ; up++) {
for(int down = up + ; down <= n; down++) {
g[i][up][down] = std::max(g[i - ][up][down], h[i - ][up][down]) + getSum(i, up, up) + getSum(i, down, down);
ans = std::max(g[i][up][down], ans);
}
}
} //out(); printf("%d\n", ans);
return ;
}
AC代码
LOJ#2668 书法家的更多相关文章
- BZOJ 2668 交换棋子(费用流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2668 题意:有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子中的棋子,最终达到目标状 ...
- 【BZOJ】【2668】【CQOI2012】交换棋子
网络流/费用流 跪跪跪,居然还可以这样建图…… 题解:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html 考虑每个点的交换限制 ...
- [Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086
额... 首先,看到这道题,第一想法就是二分答案+线段树... 兴高采烈的认为我一定能AC,之后发现n是500000... nlog^2=80%,亲测可过... 由于答案是求满足题意的最大长度-最小长 ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- Loj #2331. 「清华集训 2017」某位歌姬的故事
Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...
随机推荐
- centos安装jenkins
1.安装jdk yum install java java -version 2.安装jenkins 添加Jenkins库到yum库,Jenkins将从这里下载安装. wget -O /etc/yum ...
- DataTable克隆行
DataRow Adr = ds.Tables[].NewRow(); Adr.ItemArray = (].Rows[].ItemArray.Clone(); ds.Tables[].Rows.Ad ...
- Windows环境下使用pip install安装lxml库
lxml是Python语言和XML以及HTML工作的功能最丰富和最容易使用的库.lxml是为libxml2和libxslt库的一个Python化的绑定.它与众不同的地方是它兼顾了这些库的速度和功能完整 ...
- 一些android开发实用性网站记录
android开发一些有用的网站有很多,可以方便我们开发,记录一下哈. 1.Android源代码在线阅读:https://www.androidos.net.cn/sourcecode 2.在线Jso ...
- Glide的 java.lang.RuntimeException: Expected instanceof GlideModule, but found:X.GlideModule@2e4554f
问题一 在添加过混淆规则后,App打包的时候,发现报错了 java.lang.RuntimeException: Expected instanceof GlideModule, but found: ...
- 在 asp.net core 中使用类似 Application 的服务
在 asp.net core 中使用类似 Application 的服务 Intro 在 asp.net 中,我们可以借助 Application 来保存一些服务器端全局变量,比如说服务器端同时在线的 ...
- 数据库:MySQL实战;左链接;查询WordPress数据库中的文章内容
在1年前,我用学生价租了一个阿里云服务器(是真的便宜啊),自己在CentOS系统上用命令行搭了个WordPress的环境,开始了为期一个月使用自建博客的历程. 事实证明,博客在类似博客园这样的平台上写 ...
- TiDB 架构及设计实现
一. TiDB的核心特性 高度兼容 MySQL 大多数情况下,无需修改代码即可从 MySQL 轻松迁移至 TiDB,分库分表后的 MySQL 集群亦可通过 TiDB 工具进行实时迁移. 水平弹性扩展 ...
- React---入门(1)
React是什么? React 是一个用于构建用户界面的 JAVASCRIPT 库. React 特点 1.声明式设计 −React采用声明范式,可以轻松描述应用. 2.高效 −React通过对DOM ...
- 为什么作为下游的WSUS更新服务器总有一直处于下载状态的文件
/* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-ts ...