SGU167 I-country
嗯以前在某个DP专题了发过这道题,但是当时没码代码,现在重发一篇题解

思考阶段如何划分:
由已经处理的行数向下扩展,但是仅有行数我们无法描述状态空间
那我们再加入已经选过的格子数,这样我们似乎可以确定我们已经完成了多少行,哪些格子已经选过
但是这是凸连通块,我们靠以上两个信息还远远不够
那么我们想一想如何使阶段转移完成后最终得到的是凸连通块,再加入什么信息?
我们可以再加入每行的左端点和右端点,确定下一行端点的范围,以满足单调性
那么我们还可以再加入轮廓的单调类型
加起来5维
f[i,j,l,r,x,y]
表示前i行,选了j个格子,其中第i行选了第l到r的格子,左轮廓的单调性是x,右轮廓的单调性是r时,能构成的凸连通块的最大权值和
行数和格子数可以作为dp的“阶段”,每次转移到下一行,同时选出的格子递增,符合“阶段线性增长”的特点
然后我们会发现,我们在进行状态转移的时候,需要第i行中l到r的区间和,显然边转移边计算需要不低的复杂度,于是我们可以预处理出表示每一行的前缀和数组A,这样在计算时,l到r的区间和就可以表示为A[i][r]-A[i][l],在转移结束时,再定义两个变量p,q,表示当前行的左端点l和右端点r
然后我们来写一下状态转移方程试试:
根据我们的分析,我们可以得到4种可能状态://1表示递减,0表示递增
1.左边界列号递减,右边界列号递增(两边界都处于扩张状态)
f[i,j,l,r,1,0] = A[i][r]-A[i][l] + max{f[i-1,j-(r-l+1),p,q,1,0]};//j>r-l+1>0
` = A[i][r]-A[i][l] + max{f[i-1,0,0,0,1,0]};//j=r-l+1>0
2.左右边界列号都递减(左边界扩张,右边界收缩)
f[i,j,l,r,1,1] = A[i][r]-A[i][l] + max{max{f[i-1,j-(r-l+1),p,q,1,y]}(0<=y<=1)}
3.左右边界列号都递减(左边界收缩,右边界扩张)
f[i,j,l,r,0,0] = A[i][r]-A[i][l] + max{{f[i-1,j-(r-l+1),p,q,x,0](0<=x<=1)}}
4.左边界列号递增,右边界列号递减(两边界都处于收缩状态)
f[i,j,l,r,0,1] = A[i][r]-A[i][l] + max{max{max{f[i-1,j-(r-l+1),p,q,x,y]}(0<=y<=1)}(0<=x<=1)}(p<=l<=r<=q)
对于2,3,4的max嵌套max,可能有点难以理解
我们来想一下,我们要进行收缩,那么我们这个收缩的状态是怎么得来的?
答:由上一行扩张或收缩而来
所以当收缩右边界时,我们先比较的是上一行右边界标记扩张和右边界标记收缩的最大值,再和当前行比较
左边界收缩时同理。
这样我们就能推出2和3。
进而我们想4这种情况。
左右边界同时进行收缩,我们就要嵌套3次,先由上述确定右边界状态,再由已确定右边界状态来确定左边界状态,最后由已确定的左边界状态和右边界状态来确定当前行
//此处状态单指标记为收缩或扩张,即上一行的左/右边界由上上一行的左/右边界扩张或收缩得到
本题还要求输出方案。
在动态规划需要给出方案时,通常做法是额外使用一些与DP状态大小相同的数组记录下来每个状态,通过递归返回最初的状态,然后逐层退出的同时输出方案
#include<bits/stdc++.h>
using namespace std;
int f[][][][][][];
int lcw[][][][][][];//What did you choose on the left
int rcw[][][][][][];//What did you choose on the right
int lud[][][][][][];//The left is up or down
int rud[][][][][][];//The right is up or down
int n, m, k; int ans = , ie, le, re, xe, ye; int i, j, l, r, il, ir, x, y; int a[][], b[][]; inline int read() {
int x = , y = ;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') y = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + ch - '';
ch = getchar();
}
return x * y;
} inline void update(int val, int L, int R, int X, int Y) {
if(val < f[i][j][l][r][x][y]) return;
f[i][j][l][r][x][y] = val;
lcw[i][j][l][r][x][y] = L, rcw[i][j][l][r][x][y] = R;
lud[i][j][l][r][x][y] = X, rud[i][j][l][r][x][y] = Y;
} void print(int i, int j, int l, int r, int x, int y) {
if(!j) return;
print(i - , j - (r - l + ), lcw[i][j][l][r][x][y], rcw[i][j][l][r][x][y], lud[i][j][l][r][x][y], rud[i][j][l][r][x][y]);
for(j = l; j <= r; ++j) printf("%d %d\n", i, j);
} int main() {
freopen("input.in", "r", stdin);
freopen("output.out", "w", stdout);
memset(f, 0xcf, sizeof(f));
n = read(), m = read(), k = read();
for(i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) {
a[i][j] = read();
b[i][j] = b[i][j - ] + a[i][j];
}
for(i = ; i <= n; ++i)
for(j = ; j <= k; ++j)
for(l = ; l <= m; ++l)
for(r = l; r <= m; ++r) {//后两个维度,0表示递增,1表示递减
int len = r - l + , pow;
if(len > j) break;
pow = b[i][r] - b[i][l - ];
for(x = ; x < ; ++x)
for(y = ; y < ; ++y)
update(pow, m, , x, y);
x = y = ;
for(int p = l; p <= r; ++p)
for(int q = p; q <= r; ++q)
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
x = y = ;
for(int p = ; p <= l; ++p)
for(int q = r; q <= m; ++q) {
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
}
x = , y = ;
for(int p = l; p <= r; ++p)
for(int q = r; q <= m; ++q) {
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
}
x = , y = ;
for(int p = ; p <= l; ++p)
for(int q = l; q <= r; ++q) {
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
update(f[i - ][j - len][p][q][][] + pow, p, q, , );
}
}
for(i = ; i <= n; ++i)
for(l = ; l <= m; ++l)
for(r = l; r <= m; ++r)
for(x = ; x < ; ++x)
for(y = ; y < ; ++y) {
if(ans < f[i][k][l][r][x][y]) {
ans = f[i][k][l][r][x][y];
ie = i, le = l, re = r,
xe = x, ye = y;
}
}
printf("Oil : %d\n", ans);
print(ie, k, le, re, xe, ye);
return ;
}
SGU167 I-country的更多相关文章
- wifi的country code
转自:http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.htmlCountry A 2 A 3 Number ------------- ...
- ural 1073. Square Country
1073. Square Country Time limit: 1.0 secondMemory limit: 64 MB There live square people in a square ...
- 最小生成树 kruskal hdu 5723 Abandoned country
题目链接:hdu 5723 Abandoned country 题目大意:N个点,M条边:先构成一棵最小生成树,然后这个最小生成树上求任意两点之间的路径长度和,并求期望 /************** ...
- 01背包 URAL 1073 Square Country
题目传送门 /* 题意:问n最少能是几个数的平方和 01背包:j*j的土地买不买的问题 详细解释:http://www.cnblogs.com/vongang/archive/2011/10/07/2 ...
- 计算机学院大学生程序设计竞赛(2015’12)The Country List
The Country List Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 5723 Abandoned country(落后渣国)
HDU 5723 Abandoned country(落后渣国) Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 ...
- HDU 5723 Abandoned country (最小生成树 + dfs)
Abandoned country 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5723 Description An abandoned coun ...
- [转]How to convert IP address to country name
本文转自:http://www.codeproject.com/Articles/28363/How-to-convert-IP-address-to-country-name Download ...
- Zoj3332-Strange Country II(有向竞赛图)
You want to visit a strange country. There are n cities in the country. Cities are numbered from 1 t ...
- ural 1698. Square Country 5(记忆化搜索)
1698. Square Country 5 Time limit: 2.0 secondMemory limit: 64 MB The first arithmetical operation ta ...
随机推荐
- (转) jsp学习笔记
fromhttp://www.cnblogs.com/tao975/p/4445070.html 什么是JSP JSP的优势 JSP的劣势 JSP与PHP的比较 JSP工作原理 JSP的九大内置对象 ...
- IntelliJ IDEA 热加载
修改java文件后 win按:Ctrl+Shift+F9 mac按:cmd+Shift+F9 tomcat-maven-plugin 启动的项目也用这个快捷键热加载
- linux内存相关好文(转)
话说团队的兄弟有一天问我,为啥咱唯一的一个服务器,内存都用完了,我还想在上面测性能呢.我一听,第一反应:不可能!我说你胡扯呢吧,咱那可是16G的一个物理机,上面就跑了git服务器,怎么可能把内存吃完了 ...
- 【Foreign】Uria [欧拉函数]
Uria Time Limit: 20 Sec Memory Limit: 512 MB Description 从前有个正整数 n. 对于一个正整数对 (a,b),如果满足 a + b ≤ n 且 ...
- 「6月雅礼集训 2017 Day7」回转寿司
[题目大意] 给一个n个数的序列,q次操作,每次选择区间$[l,r]$,给出数p,对于区间$[l,r]$的每个数$x$,做如下操作: 如果$x > p$,就交换$x$和$p$.求每次操作后$p$ ...
- Android检测View的可见性
Android中我们经常会用到判断View的可见行,当然有人会说View.VISIBLE就可以了,但是有时候这个真是满足不了,有时候我们为了优化,在View滚到得不可见的时候或者由于滚到只显示了部分内 ...
- Android跳转到拨打电话的页面
在Android6.0之后,拨打电话需要用户授予动态权限,项目中有此需求,有一种简单的方法,直接携带电话号码跳转到系统拨打电话的页面,很多应用也是这么做的,这样可以减轻工作量 代码如下: Androi ...
- MediaWiki安装配置(Linux)【转】
转自:http://blog.csdn.net/gao36951/article/details/43965527 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 1Media ...
- python近期遇到的一些面试问题(二)
1. 解释什么是栈溢出,在什么情况下可能出现. 栈溢出是由于C语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围.在Python中, ...
- pycaffe使用.solverstate文件继续训练
import caffe solver_file = "solver.prototxt" solverstate = "xx.solverstate" caff ...