Luogu P10997 Partition 题解 [ 蓝 ] [ 分割线 dp ]
Partition:一道 dp 神题,用到了以轮廓线的轨迹来做 dp 的技巧,和敲砖块这题的状态设计有点相似。
观察
首先观察样例,发现整张图可以看作是被两条线分隔开的。同时每个颜色的四个方向上又存在一大堆奇怪的性质,很容易发现这两条线一条是从左上到右下的线,另一条是从右下到左上的线。
暴力 dp
有了这两条线,并且发现这两条线一定不会往回走(比如往上走的线,不会在某个地方往下走),即无后效性,那么我们就可以暴力 dp 了。
设计 \(dp_{i,j,k}\) 表示在第 \(i\) 行时,两条线分别在第 \(j\) 列与第 \(k\) 列时的最大值。
然后暴力转移一下就好了,这种做法还要对两条线的位置关系进行分讨转移,比较麻烦,复杂度又高,因此我们需要从另一个角度考虑 dp。
正解
我们观察每个颜色各自的贡献,可以发现,红色的权值为 \(1\),且其他颜色的权值都比 \(1\) 大。因此我们可以把染色的过程看作先把每个数涂上红色,然后其他颜色的权值减小了 \(1\),再来 dp。
这样以后橙色的权值为 \(1\),黄色的权值为 \(2\),绿色的权值为 \(3\)。再来观察图的形态,可以发现橙色和绿色是连在一起的。所以我们可以把橙色和绿色的部分统一先填上色,过程就和上面暴力 dp 一样,从右上到左下进行 dp,只不过我们只需要维护一条线的路线,复杂度降低了很多。
从右上到左下具体的转移方程如下:
\]
其中 \(f_{i,j}\) 表示第 \(i\) 行的前缀和数组,\(a_{i,j}\) 表示第 \(i\) 行第 \(j\) 列的元素。
最后黄色和绿色的权值都变成 \(2\) 了,因为他们两个依然是相邻的,所以我们可以从左上到右下做一次 dp,做最后一次涂色,统计进答案就好了。
一共做了两次 dp,时间复杂度为 \(O(nm)\)。
代码
在实现上我们在 dp 时可以多进行一次,这样统计答案时就不用一个一个取最大值,只需要取最后转移到的地方就好了。
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
int n,m;
ll a[2005][2005],dp1[2005][2005],dp2[2005][2005],ans=0,f[2005][2005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
ans+=a[i][j];
f[i][j]=f[i][j-1]+a[i][j];
}
}
memset(dp1,-0x3f,sizeof(dp1));
memset(dp2,-0x3f,sizeof(dp2));
for(int i=1;i<=m+1;i++)dp1[0][i]=dp2[0][i]=0;
for(int i=1;i<=n+1;i++)
{
for(int j=m+1;j>=1;j--)
{
dp1[i][j]=max(dp1[i-1][j]+f[i][m]-f[i][j-1],dp1[i][j+1]+a[i][j]);
}
for(int j=1;j<=m+1;j++)
{
dp2[i][j]=max(dp2[i-1][j]+f[i][j-1],dp2[i][j-1]+a[i][j-1]);
}
}
cout<<ans+dp1[n+1][1]+2*dp2[n+1][m+1];
return 0;
}
Luogu P10997 Partition 题解 [ 蓝 ] [ 分割线 dp ]的更多相关文章
- 【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)
ACM字符串 .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块! ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个 输入 ...
- 题解 BZOJ1026 & luogu P2657 [SCOI2009]windy数 数位DP
BZOJ & luogu 看到某大佬AC,本蒟蒻也决定学习一下玄学的数位$dp$ (以上是今年3月写的话(叫我鸽神$qwq$)) 思路:数位$DP$ 提交:2次 题解:(见代码) #inclu ...
- BZOJ 1003 物流运输 题解 【SPFA+DP】
BZOJ 1003 物流运输 题解 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的 ...
- Luogu P4643 【模板】动态dp
题目链接 Luogu P4643 题解 猫锟在WC2018讲的黑科技--动态DP,就是一个画风正常的DP问题再加上一个动态修改操作,就像这道题一样.(这道题也是PPT中的例题) 动态DP的一个套路是把 ...
- Luogu P4643 【模板】动态dp(矩阵乘法,线段树,树链剖分)
题面 给定一棵 \(n\) 个点的树,点带点权. 有 \(m\) 次操作,每次操作给定 \(x,y\) ,表示修改点 \(x\) 的权值为 \(y\) . 你需要在每次操作之后求出这棵树的最大权独立集 ...
- luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索
题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...
- [NOIP10.3模拟赛]3.w题解--神奇树形DP
题目链接: 咕 闲扯: 这题考场上把子任务都敲满了,5个namespace,400行11k 结果爆0了哈哈,因为写了个假快读只能读入一位数,所以手测数据都过了,交上去全TLE了 把边分成三类:0. 需 ...
- BZOJ 2669 Luogu P3160 [CQOI2012]局部极小值 (容斥原理、DP)
题目链接 (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2669 (luogu) https://www.luogu.org/prob ...
- 题解——洛谷P2734 游戏A Game 题解(区间DP)
题面 题目背景 有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的任意一端取一个数,取数后该数字被去掉并累加到本玩家的 ...
- [BZOJ 1260][CQOI2007]涂色paint 题解(区间DP)
[BZOJ 1260][CQOI2007]涂色paint Description 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为 ...
随机推荐
- Redis工具之redis_rdb_tools
redis_rdb_tools工具的介绍: 解析redis的dump.rdb文件,分析内存,以JSON格式导出数据.|提供的功能有: 1. 生成内存报告 2. 转储文件到JSON 3. 使用标准的di ...
- Educational Codeforces Round 65 (Rated for Div
D - Bicolored RBS 给定一个括号序列,现在你必须对每一个括号涂成蓝色或红色,要求使得涂完后的红色括号和蓝色括号序列都必须是合法的括号序列,设红色括号形成的的括号序列的深度为\(dep_ ...
- Ubuntu默认启动到字符界面
修改/etc/default/grub sudo cp /etc/default/grub /etc/default/grub.bak sudo chmod 0777 /etc/default/gru ...
- 利用smtp发邮件
小功能,备忘 MailMessage objMailMessage = new MailMessage();//引入System.Net objMailMessage.From = new MailA ...
- 【杂谈】服务端能同时处理多少个 Socket 连接?背后的资源与限制分析
一个服务端进程能同时连接多少个 Socket? 要理解一个服务端进程能同时支持多少个连接,首先我们需要明确一个 socket 连接 的表示方式.一个连接由四个部分组成:[LocalIP:LocalPo ...
- IOS热重载工具InjectionIII
IOS热重载工具InjectionIII 支持 OC.Swift 以及 Swift 和 OC 混编项目的 UI 热重载工具,采取在模拟器(真机不支持)注入方式实现 UI 热重载,修改完 UI 直接 c ...
- Netty系列之Netty安全性
1.1. 严峻的安全形势 1.1.1. OpenSSL Heart bleed漏洞 2014年上半年对网络安全影响最大的问题就是OpenSSL Heart bleed漏洞,来自Codenomicon和 ...
- Qt/C++原创项目作品精选(祖传原创/性能凶残)
00 前言说明 从事Qt开发十年有余,一开始是做C#.NET开发的,因为项目需要,转行做嵌入式linux开发,在嵌入式linux上做可视化界面开发一般首选Qt,当然现在可选的方案很多比如安卓,但是十多 ...
- Qt编写安防视频监控系统24-自定义悬浮条
一.前言 自定义悬浮条功能集成在通用视频控件中,就是提供一个顶部的悬浮条,放一排功能按钮,有抓拍.录像.云台控制.关闭等,相当于可以直接单击对应的按钮针对该通道的视频进行操作,悬浮条的含义就是鼠标移入 ...
- Qt编写可视化大屏电子看板系统15-曲线面积图
一.前言 曲线面积图其实就是在曲线图上增加了颜色填充,单纯的曲线可能就只有线条以及数据点,面积图则需要从坐标轴的左下角和右下角联合曲线形成完整的封闭区域路径,然后对这个路径进行颜色填充,为了更美观的效 ...