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问题中,有着几个比较经典而基础的模 ...
随机推荐
- 正说PropertyValuesProvider的应用
Github地址:https://github.com/andyslin/spring-ext 编译.运行环境:JDK 8 + Maven 3 + IDEA + Lombok spring-boot: ...
- ubuntu显卡(NVIDIA)驱动以及对应版本cuda&cudnn安装
(已禁用集显,禁用方法可自行百度) 驱动在线安装方式进入tty文本模式ctrl+alt+F1关闭显示服务sudo service lightdm stop卸载原有驱动sudo apt-get remo ...
- mysql——查询语句——单表查询——(概念)
一.基本查询语句 select的基本语法格式如下: select 属性列表 from 表名和视图列表 [ where 条件表达式1 ] [ group by 属性名1 [ having 条件表达式2 ...
- 分享个昨天学的,sqlserver查表的所有列的列名,类型,长度的sql
select a.name as 列名, a.length as 长度,b.name as 类型 from syscolumns a left join systypes b on a.xtype ...
- MSF魔鬼训练营-3.5.3 MSF中常用的关于数据库的命令
渗透测试数据库用来保存渗透测试过程中获取的各种数据,很多时候你重启了kali发现连接不上数据库了,其实就是因为这个服务没开 MSF所使用的数据库时postgresql root@kali:/# ser ...
- 纯前端表格控件SpreadJS V12.1 隆重登场,专注易用性,提升用户体验
一款优秀的开发工具,在更新迭代中,除了要满足不同场景的业务需求,也需不断优化已有功能,尤其是细节方面,要能为用户带来使用体验和开发效率的提升. 作为一款备受业界专家和开发者认可的纯前端类Excel ...
- 用Java实现对英文版《飘》的文件读取与写入操作
从文件读入<飘>的英文版,并将结果输出到文件中 要求一: 实现对英文版<飘>的字母出现次数统计 package File; import java.io.FileInputSt ...
- MySQL的事务和锁
MySQL的事务和锁 阅读目录 什么是事务 事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作:这些操作作为一个整体一起向系统提交,要么都执行.要么都不执行:事务是一组不可再 ...
- 分布式唯一ID生成器Twitter
分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有些时候我们希望能使用一种简单一 ...
- hashmap存储数据
在HashMap中,为什么不能使用基本数据类型作为key? 其实和HashMap底层的存储原理有关,HashMap存储数据的特点是:无序.无索引.不能存储重复元素. 存储元素采用的是hash表存储数据 ...