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\) 个音符, ...
随机推荐
- html&css学习一
HTML标签 HTML骨架 <HTML> <head> <title></title> </head> <body> </ ...
- 微信小程序 canvas 绘制圆形状
page({ // 绘制canvas drawCanvas:function(){ const ctx = wx.createCanvasContext('poster') // 画圆形二维码 thi ...
- python 生成18年写过的博客词云
文章链接:https://mp.weixin.qq.com/s/NmJjTEADV6zKdT--2DXq9Q 回看18年,最有成就的就是有了自己的 博客网站,坚持记录,写文章,累计写了36篇了,从一开 ...
- 使用PDF.JS实现pdf文件在线预览时,报文件被损坏的错误
首先大概说明一下问题出现的背景:我用PDF.JS实现文件在线预览,参考网上的办法,在jsp文件中使用 <iframe src="<c:url value="js/gen ...
- 1 minute教会你shell
Shell模板 #!/bin/bash ####################################################### # $Name: shell_template. ...
- django mongodb配置
#settings.py import os from mongoengine import * BASE_DIR = os.path.dirname(os.path.dirname(os.path. ...
- Keepalibed监控nginx
配置Keepalived监控nginx --wang 目的: 通过Keepalived实现对nginx的监控,每两秒扫描一次,如果nginx关闭,尝试重启nginx,两秒后检查nginx是否启动,如果 ...
- Java基础系列--04_数组
一维数组: (1)数组:存储同一种数据类型的多个元素的容器. (2)特点:每一个元素都有编号,从0开始,最大编号是数组的长度-1. 编号的专业叫法:索引 (3)定义格式 A:数据类型[] 数组名;(一 ...
- bilibili用户信息全栈爬取
- gdb cheat sheet
0x01 控制流 r run,运行程序. r < a.txt run,重定向输入 si step instruction 进入函数 ni next instruction 下一 ...