CH5104 I-country[线性DP+分类讨论]
rt,求给定格子数的凸连通块最大价值。
其实刚看到凸连通块的时候有点懵逼,因为不知道这是啥,网上也没定义。瞟了一眼lyd题解第一行,说是左端先(非严格)递减,再(非严格)递增,右端先(非严格)递增,再(非严格)递减的就是凸连通块。
那就只看左右端的单调性变化情况。。考虑到每行选的连续格子和上一行有联系,用DP转移。
$f[i][k][l][0/1][r][0/1]$表示到第$i$行,选了$k$个格子,选的左端点是$l$,和上一行的关系是单调减或增(0 or 1),右端点是$r$,单调性同左的状态下最大价值。【因为要考虑单调性的变化情况,故需要设计01状态】
然后就是枚举行,左右端点,上一行的左右端点,以及选格子数,根据单调情况来无脑转移。
分五种情况大力讨论即可。
- 从这一行才开始选
- 左侧增,右侧增
- 左侧增,右侧减
- 左侧减,右侧增
- 左侧减,右侧减
然后每种情况具体画线段图就可以知道从上一行的什么单调情况转移了,不放latex了,直接看code。
理论复杂度$O(N^7)$,$N \leqslant 15$,按说1000ms是过不了的,不过。。枚举过程常数大概在$\frac{1}{8}$~$\frac{1}{4}$左右,再带点前缀和、区间长度预处理什么的卡卡也就能过去了。
WA:
因为码力不行,对于这种大力讨论的题,真心不容易一遍敲对。line45~48转移的时候忘了加sum。。不过也是很显眼的错误呢,毕竟WA答案逼近正解时基本是初始化和转移的个别一两句话写错,这时候应将肉眼调试范围放至转移的部分。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define ddbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
#define rep(i,a,b) for(register int i=a;i<=b;++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 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=;
struct thxorz{
int l,r,dl,dr;
thxorz(int l=,int r=,int dl=,int dr=):l(l),r(r),dl(dl),dr(dr){}
}g[N][N*N][N][][N][];
int f[N][N*N][N][][N][],len[N][N],val[N][N][N],mp[N][N];
int n,m,K,sum,ans; int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
read(n),read(m),read(K);
rep(i,,n){
rep(j,,m)read(mp[i][j]),val[][][j]=val[][][j-]+mp[i][j];
rep(j,,m)rep(l,,j)val[i][l][j]=val[][][j]-val[][][l-];
}
memset(val[][],,sizeof val[][]);
rep(i,,m)rep(j,i,m)len[i][j]=j-i+;
rep(i,,m)rep(j,i,m)f[][len[i][j]][i][][j][]=f[][len[i][j]][i][][j][]=f[][len[i][j]][i][][j][]=f[][len[i][j]][i][][j][]=val[][i][j];
rep(i,,n)rep(l,,m)rep(r,l,m){
sum=val[i][l][r];
f[i][len[l][r]][l][][r][]=f[i][len[l][r]][l][][r][]=f[i][len[l][r]][l][][r][]=f[i][len[l][r]][l][][r][]=val[i][l][r];
rep(L,,l)rep(R,l,r)rep(k,len[l][r]+len[L][R],len[l][r]+len[L][R]+(i-)*m){
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
}
rep(L,,l)rep(R,r,m)rep(k,len[l][r]+len[L][R],len[l][r]+len[L][R]+(i-)*m){
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
}
rep(L,l,r)rep(R,L,r)rep(k,len[l][r]+len[L][R],len[l][r]+len[L][R]+(i-)*m){
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
}
rep(L,l,r)rep(R,r,m)rep(k,len[l][r]+len[L][R],len[l][r]+len[L][R]+(i-)*m){
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
if(MAX(f[i][k][l][][r][],f[i-][k-len[l][r]][L][][R][]+sum))g[i][k][l][][r][]=thxorz(L,R,,);
}
}
thxorz orz;int k=K,row;
rep(i,(K-)/m+,n)rep(l,,m)rep(r,l,m){
if(MAX(ans,f[i][K][l][][r][]))orz=thxorz(l,r,,),row=i;
if(MAX(ans,f[i][K][l][][r][]))orz=thxorz(l,r,,),row=i;
if(MAX(ans,f[i][K][l][][r][]))orz=thxorz(l,r,,),row=i;
if(MAX(ans,f[i][K][l][][r][]))orz=thxorz(l,r,,),row=i;
}
while(k){
rep(i,orz.l,orz.r)mp[row][i]=-;k-=len[orz.l][orz.r];
orz=g[row--][k+len[orz.l][orz.r]][orz.l][orz.dl][orz.r][orz.dr];
}
printf("Oil : %d \n",ans);
rep(i,,n)rep(j,,m)if(mp[i][j]==-)printf("%d %d\n",i,j);
return ;
}
CH5104 I-country[线性DP+分类讨论]的更多相关文章
- dp+分类讨论 Gym 101128E
题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/detail ...
- 【CH5104】I-country 线性dp+路径输出
pre:在网格中,凸多边形可以按行(row)分解成若干段连续的区间 [ l , r ] ,且左端点纵坐标的值(col)满足先减后增,右端点纵坐标先增后减. 阶段:根据这个小发现,可以将阶段设置成每一行 ...
- C. Functions again DP + 分类讨论
http://codeforces.com/contest/789/problem/C 首先按题目要求处理出dis数组. 那么对于任意一个区间,[L, R],是dis[L] - dis[L + 1] ...
- Codeforces 521E - Cycling City(点双连通分量+分类讨论)
Codeforces 题面传送门 & 洛谷题面传送门 大家都是暴力找生成树然后跳路径,代码不到 50 行(暴论)的一说--好,那本蒟蒻决定提供一种代码 150 行,但复杂度也是线性的分类讨论做 ...
- Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array 分类讨论连续递推dp
题意:给出一个 数列 和一个x 可以对数列一个连续的部分 每个数乘以x 问该序列可以达到的最大连续序列和是多少 思路: 不是所有区间题目都是线段树!!!!!! 这题其实是一个很简单的dp 使用的是分 ...
- D. Easy Problem dp(有衔接关系的dp(类似于分类讨论) )
D. Easy Problem dp(有衔接关系的dp(类似于分类讨论) ) 题意 给出一个串 给出删除每一个字符的代价问使得串里面没有hard的子序列需要付出的最小代价(子序列不连续也行) 思路 要 ...
- P5979 [PA2014]Druzyny dp 分治 线段树 分类讨论 启发式合并
LINK:Druzyny 这题研究了一下午 终于搞懂了. \(n^2\)的dp很容易得到. 考虑优化.又有大于的限制又有小于的限制这个非常难处理. 不过可以得到在限制人数上界的情况下能转移到的最远端点 ...
- Codeforces 1461F - Mathematical Expression(分类讨论+找性质+dp)
现场 1 小时 44 分钟过掉此题,祭之 大力分类讨论. 如果 \(|s|=1\),那么显然所有位置都只能填上这个字符,因为你只能这么填. scanf("%d",&n);m ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
随机推荐
- mybatis-generator自动生成代码时,只生成insert方法
今天使用mybatis-generator自动生成代码时,发现只能生成insert方法, 以前所有的方法都是可以生成的,查看网上解决办法和检查数据库表结构后, 发现2种可以解决的办法: 1.修改myb ...
- 刷新页面后,让控制台的js代码继续执行
在各种限时,秒杀活动中,有个自动循环的点击的工具是很重要的. 为了方便起见,我们把Js代码放在浏览器的控制台执行,但是刷新页面后,js代码就清空了,也就无法执行. 可以用js代码实现一个不受页面刷新影 ...
- ERROR】Unable to open underlying table which is differently defined or of non-MyISAM type or ...
Error: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn’t ...
- redis缓存服务器
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.使用redis的好处? 速度快,因为数据存在内存,类似hashmap,hashmap的优势就是查找和操作的时间 ...
- 解析之Apache解析
- ASP.NET Session详解(转)
ASP.NET Session详解 本文章来自:http://blog.163.com/adam601@126/blog/static/22506317200932824210996/ 当用户在 We ...
- 【C/C++】什么是类型安全
什么是类型安全 转自:http://hi.baidu.com/chenfalei/blog/item/f33ac0133500ac21dd540186.html 编程语言的最终梦想:静态类型安全 常听 ...
- SYN攻击源码
一.linux下源代码实现/* syn flood by wqfhenanxc. * random soruce ip and random sourec port. * use #include & ...
- 洛谷 P1268 树的重量 题解
题面 目的:求出树的各边长度 条件:每个节点之间最短路.整个图中不存在负边 我们可以每一次把一个点加入树内,求出这个点和已经构建好的树的边的长度: 这个长度抽象理解一下就是(dis[i][j]+dis ...
- 如何用纯 CSS 创作一个慧星拖尾效果的 loader 动画
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/YLRLaM 可交互视频教 ...