SGU 167.I-country
时间限制:0.75s
空间限制:65M
题意:
在一个n*m(n,m<=15)的网格中,每个格子有一个值,现在从网格中取出k(k<=n*m)个,保证在选中的格子中从任意一个格子去另外的所有格子最多只用到四种(上,下,左,右)操作中的两种,并使得到的值最大。输出该值和选中的格子坐标。
Solution
从选中的网格的任意一个去所有格子只用两种操作:
左图一种满足条件的网格集合,右图的(1,3)到(3,2)必需使用(左,下,右)三种操作才能到达,是不符合要求的。
注意到,满足条件的网格集合一定不会出现凹形,因为凹形的上下两个突出点中的格子不可能只用两个操作到达。
由此用0,1记录左右两边是 向外突出还是向内收缩。
当一行的一边向内收缩时便不可以再向外突出了。
接下来是按行dp
f[row][l][r][opl][opr][k],代表第row行,取第l列带第r列的格子,左边格子突出状态为opl,右边为opr,当前共选择了k个格子
记录路径时如果用结构体记录下所有的状态的上一个状态需要15*15*2*2*225 * size(int)*6的空间.
爆一次内存后,想到对于上一个状态row和k可以推出,只需要记录(l,r,opl,opr)即可,而(l,r,opl,opr)都是不超过16的数,那么可以用一个int形用16进制存下
存的时候用 record=(l << 12) + (r << 8) + (opl << 4) + (opr)
用的时候
上一个(row,l,r,opl,opr,k)
可以由当前的(row - 1, (record >> 12) % 16, (record >> 8) % 16, (record >> 4) % 16, record % 16, k - r + l - 1)得到
这道题需要注意的地方有很多,不一一列举.总的来说是一道值得一做的好题
参考代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#define pdx pr[row][l][r][opl][opr][k]
#define val(r,a,b) g[r][b] - g[r][a - 1]
using namespace std;
int f[16][16][16][2][2][230], g[16][16];
int pr[16][16][16][2][2][230];
int n, m, k, ans;
int a, al, ar, aol, aor;
/*
op=0 / 左突
op=1 \ 右突
*/
//当前状态向下更新
void update (int row, int l, int r, int opl, int opr, int s) {
if (row == n) return ;
for (int nl = (opl == 0 ? 1 : l); nl <= r; nl++)
for (int nr = max (l, nl); nr <= (opr == 0 ? r : m); nr++) {
int t1, t2;
if (nl == l) t1 = opl;
else
t1 = (nl < l ? 0 : 1);
if (nr == r) t2 = opr;
else
t2 = (nr < r ? 0 : 1);
if (f[row + 1][nl][nr][t1][t2][s + (nr - nl + 1)] <
f[row][l][r][opl][opr][s] + val (row + 1, nl, nr) ) {
f[row + 1][nl][nr][t1][t2][s + (nr - nl + 1)] =
f[row][l][r][opl][opr][s] + val (row + 1, nl, nr);
//记录上一个状态 , 16进制状态压缩
pr[row + 1][nl][nr][t1][t2][s + (nr - nl + 1)] =
(l << 12) + (r << 8) + (opl << 4) + (opr);
}
}
} void dp() {
for (int row = 1; row <= n; row++)
for (int l = 1; l <= m; l++)
for (int r = l; r <= m; r++)
for (int opl = 0; opl < 2; opl++)
for (int opr = 0; opr < 2; opr++) {
f[row][l][r][opl][opr][r - l + 1] = g[row][r] - g[row][l - 1];
for (int s = r - l + 1; s <= k; s++)
if (f[row][l][r][opl][opr][s] > 0 ) {
update (row, l, r, opl, opr, s);
if (s == k)//记录最大解
if (f[row][l][r][opl][opr][s] > ans) {
ans = f[row][l][r][opl][opr][s];
a = row, al = l, ar = r, aol = opl, aor = opr;
}
}
}
}
//输出
void write (int row, int l, int r, int opl, int opr, int k) {
if (row == 0 || k <= 0) return;
for (int i = l; i <= r; i++)
printf ("%d %d\n", row, i);
write (row - 1, (pdx >> 12) % 16, (pdx >> 8) % 16,
(pdx >> 4) % 16, pdx % 16, k - r + l - 1);
}
int main() {
#ifndef ONLINE_JUDGE
freopen ("in.txt", "r", stdin);
#endif // oline_judge
scanf ("%d %d %d", &n, &m, &k);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
scanf ("%d", &g[i][j]);
g[i][j] += g[i][j - 1];
}
memset (f, -1, sizeof f);
dp();
printf ("Oil : %d\n", ans);
write (a, al, ar, aol, aor, k);
return 0;
}
SGU 167.I-country的更多相关文章
- SGU 520 Fire in the Country(博弈+搜索)
Description This summer's heat wave and drought unleashed devastating wildfires all across the Earth ...
- 新概念英语(1-67)The weekend
新概念英语(1-67)The weekend What are the Johnsons going to do at the weekend? A:Hello. Were you at the bu ...
- SGU 分类
http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...
- wifi的country code
转自:http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.htmlCountry A 2 A 3 Number ------------- ...
- SGU 495. Kids and Prizes
水概率....SGU里难得的水题.... 495. Kids and Prizes Time limit per test: 0.5 second(s)Memory limit: 262144 kil ...
- ural 1073. Square Country
1073. Square Country Time limit: 1.0 secondMemory limit: 64 MB There live square people in a square ...
- ACM: SGU 101 Domino- 欧拉回路-并查集
sgu 101 - Domino Time Limit:250MS Memory Limit:4096KB 64bit IO Format:%I64d & %I64u Desc ...
- 【SGU】495. Kids and Prizes
http://acm.sgu.ru/problem.php?contest=0&problem=495 题意:N个箱子M个人,初始N个箱子都有一个礼物,M个人依次等概率取一个箱子,如果有礼物则 ...
- SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operati ...
随机推荐
- 许令波老师的java的IO机制分析文章
深入分析 Java I/O 的工作机制 I/O 问题可以说是当今互联网 Web 应用中所面临的主要问题之一,因为当前在这个海量数据时代,数据在网络中随处流动.这个流动的过程中都涉及到 I/O 问题,可 ...
- Delphi中TxmlDocument控件的用法 转
Delphi中对XML文件的解析做的很好,比直接使用MS的MSXML2_TLB中的接口要方便很多,现称述于下面. 在讲之前先给出一个XML实例,在讲某些部分是要结合实例比较容易理解. 1<?xm ...
- MessageFormat.format处理单引号和大括号
在MessageFormat.format方法中组装jason数据字符串:{code:"w1",des:"w2"},起止分别有左大括号和右大括号.方法是将单引号 ...
- Unity 的 unitypackage 的存放路径
Windows,C:\Users\<username>\AppData\Roaming\Unity\Asset Store Mac OS X,~/Library/Unity/Asset S ...
- Java Web中web.xml的作用
每一个javaWeb工程都有一个web.xml配置文件,那么他到底有什么作用呢?它是每一个web工程都必的必须的吗? web.xml文件是用来初始化工程配置信息的,比如说welcome页面,fil ...
- lightoj1017 dp
题目链接:http://lightoj.com/volume_showproblem.php?problem=1017 #include <cstdio> #include <cst ...
- 网络子系统41_inet_peer平衡二叉树的删除
//1.p存在左孩子,则使用p的左孩子的最右孩子替换p,然后重平衡树 //2.p不存在左孩子,则使用p的右孩子替换p,然后重平衡树 1.1 static void unlink_from_pool(s ...
- 高性能、高流量Java Web站点打造的22条建议
@http://www.csdn.net/article/2013-12-20/2817861-22-recommendations-for-building-effective-high-traff ...
- CMDLINE的解析
在linux的config文件中有一个特殊的宏定义CMDLINE,以前也一直在使用这个宏的参数,但是真正这个宏的解析和使用却不怎么明确.这次有机会多对它有些了解,不妨把这个浅显的认识说出来,记下来. ...
- android_小总结_方法过时的兼容处理
随着android系统的升级,有些过时的方法已经不再使用,但是又要兼容老的版本,所以这个时候可以使用反射来处理下 举个列子pull_to_refresh 中有个方法找不到==initializeScr ...