Luogu P9180 [COCI2022-2023#5] Slastičarnica 题解 [ 蓝 ] [ 区间 dp ] [ dp 状态优化 ] [ 前缀和优化 ]
Slastičarnica:非常好的区间 dp 题。
暴力
不难设计出暴力状态:\(dp_{q,i,j}\) 表示进行到第 \(q\) 次操作,剩下区间 \([i,j]\) 是否可行。
直到全部状态都为 \(0\) 的时候输出即可。
期望得分 \(19pts\)。
优化(假)
观察到每个 \(dp\) 状态都只有两个值 \(0,1\),那么我们可以考虑将状态中的某一维放进 \(dp\) 值里。
首先尝试把 \(q\) 换进去,状态设计为 \(dp_{i,j}\) 为剩余区间 \([i,j]\) 时进行的最大操作数为 \(q\)。
那么我们怎么转移?从大往小枚举区间,然后根据当前进行的操作,每次查询满足要求的前缀后缀,转移一下即可。
此时我们不难发现,\(q\) 的最大值只能是 \(n\),根本无法取到更大。这就是这题的诈骗点。
时间复杂度是 \(O(n^3)\) 的,而我们可以发现无法继续优化下去(四边形不等式等都用不了),就要换一种思路。
贪心
显然,对于一段区间而言,长度越长,自然是对答案更优。为什么?因为每次操作都可以留出更多的空间来操作。
于是我们考虑固定左端点,把右端点换出来。
正解
设计状态 \(dp_{q,i}\) 表示进行到了第 \(q\) 次操作,左端点为 \(i\) 时的最大右端点在哪。
每次操作可以选前缀、后缀,于是我们分两种转移。
前缀
\(dp_{q,i}\) 能转移当且仅当 \([i-d,i-1]\) 能被消掉,然后转移左端点在 \(i\) 前面的 \(j\) 的所有 \(dp_{q-1,j}\) 的值。
这个可以做一个很显然的前缀和优化,不再细说。
后缀
感觉这个比较难搞。
\(dp_{q,i}\) 能转移的条件是在 \([j,dp_{q-1,j}]\) 中有能消除的后缀,同时在这些后缀中取最大的左端点转移。
观察到 \(dp_{q-1,j}\) 也在 \([1,n]\) 之间,于是我们可以预处理出对于每一个点,在他左边的最大可消除后缀的左端点在哪,这个可以 \(O(n)\) 处理出。
然后每次转移一下即可。
总体时间复杂度 \(O(\min(n,q)n)\)。
细节
特判整个序列被删完的情况。只需要在删后缀里面加特判即可。因为要删完肯定是一次删全部,那么此时就没有前缀后缀之分了,算哪个都可以。
代码
#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 unsigned long long ull;
typedef pair<int,int> pi;
int n,q,a[5005],mn[5005][5005],dp[5005][5005],rmx[5005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i];
memset(mn,0x3f,sizeof(mn));
for(int i=1;i<=n;i++)
{
mn[i][i]=a[i];
for(int j=i+1;j<=n;j++)mn[i][j]=min(mn[i][j-1],a[j]);
}
memset(dp,-1,sizeof(dp));
dp[0][1]=n;
for(int i=1;i<=min(n,q);i++)
{
bool ed=1;
int d,s,pre=-1,p=-1;
cin>>d>>s;
for(int j=1;j<=n;j++)
{
if(j-d>=1)pre=max(pre,dp[i-1][j-d]);
if(j-d>=1&&mn[j-d][j-1]>=s)dp[i][j]=max(dp[i][j],pre);
}
for(int j=1;j<=n;j++)
{
if(j-d+1>=1&&mn[j-d+1][j]>=s)p=max(p,j-d+1);
rmx[j]=p;
}
for(int j=1;j<=n;j++)
{
if(rmx[dp[i-1][j]]-1>=j)dp[i][j]=max(dp[i][j],rmx[dp[i-1][j]]-1);
if(dp[i][j]<j)dp[i][j]=-1;
if(rmx[dp[i-1][j]]==j)ed=0;
}
for(int j=1;j<=n;j++)if(dp[i][j]!=-1)ed=0;
if(ed)
{
cout<<i-1;
return 0;
}
}
cout<<q;
return 0;
}
Luogu P9180 [COCI2022-2023#5] Slastičarnica 题解 [ 蓝 ] [ 区间 dp ] [ dp 状态优化 ] [ 前缀和优化 ]的更多相关文章
- luogu P1549 棋盘问题(2) 题解
luogu P1549 棋盘问题(2) 题解 题目描述 在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,-,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数. 例如 ...
- 【luogu P1314 聪明的质监员】 题解
题目链接:https://www.luogu.org/problemnew/show/P1314 二分答案 但是计算区间贡献的时候 直接暴力会挂 前缀和加速 #include <cstdio&g ...
- BZOJ 2023 [Usaco2005 Nov]Ant Counting 数蚂蚁:dp【前缀和优化】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2023 题意: 有n个家族,共m只蚂蚁(n <= 1000, m <= 1000 ...
- 题解——洛谷P2734 游戏A Game 题解(区间DP)
题面 题目背景 有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的任意一端取一个数,取数后该数字被去掉并累加到本玩家的 ...
- 【题解】POJ1934 Trip (DP+记录方案)
[题解]POJ1934 Trip (DP+记录方案) 题意: 传送门 刚开始我是这么设状态的(谁叫我DP没学好) \(dp(i,j)\)表示钦定选择\(i\)和\(j\)的LCS,然而你会发现这样钦定 ...
- 【题解】剪纸条(dp)
[题解]剪纸条(dp) HRBUST - 1828 网上搜不到题解?那我就来写一篇吧哈哈哈 最优化问题先考虑\(dp\),设\(dp(i)\)表示将前\(i\)个字符(包括\(i\))分割成不相交的回 ...
- 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)
[题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...
- 【题解】地精部落(DP)
[题解]地精部落(DP) 设\(f_i\)表示强制第一个是谷的合法方案数 转移枚举一个排列的最大值在哪里,就把序列分成了互不相干的两个部分,把其中\(i-1\choose j-1\)的数字分配给前面部 ...
- 【luogu P2279 [HNOI2003]消防局的设立】 题解
题目链接:https://www.luogu.org/problemnew/show/P2279 想怎么贪怎么贪 #include <queue> #include <cstdio& ...
- 【luogu P2762 太空飞行计划问题】 题解
题目链接:https://www.luogu.org/problemnew/show/P2762 算是拍照那个题的加强下. 输入真的很毒瘤.(都这么说但好像我的过了?) #include <qu ...
随机推荐
- Prometheus之系统安装,启动
Prometheus简介Prometheus是最初在SoundCloud上构建的开源系统监视和警报工具包. 自2012年成立以来,许多公司和组织都采用了Prometheus,该项目拥有非常活跃的开发人 ...
- python之异步任务框架Celery
官网参考: Celery 官网:http://www.celeryproject.org/ Celery 官方文档英文版:http://docs.celeryproject.org/en/latest ...
- Blazor 组件库 BootstrapBlazor 中Circle组件介绍
组件介绍 Circle进度环组件,是一个图表类组件.一般有两种用途: 显示某项任务进度的百分比. 统计某些指标的占比. 它的样子如下: 它的代码如下: <Circle Width="2 ...
- 【实战问题】-- 布隆过滤器的三种实践:手写,Redission以及Guava(2)
前面我们已经讲过布隆过滤器的原理[实战问题]-- 缓存穿透之布隆过滤器(1),都理解是这么运行的,那么一般我们使用布隆过滤器,是怎么去使用呢?如果自己去实现,又是怎么实现呢? 目录 布隆过滤器 手写布 ...
- Sortable.js笔记
1.前言 SortableJS是功能强大的JavaScript 拖拽库,更多配置项:Sortable.js中文网|配置 引入插件 <script src="https://cdn.bo ...
- vue3 封装api接口
新建axiosj.ts import axios from 'axios'; import { showMessage } from "./status"; // 引入状态码文件 ...
- Git 克隆部分文件
使用 sparse-checkout (推荐) git clone \ -b master \ --depth=1 \ --filter=blob:none \ --sparse \ <repo ...
- Mysql之myisam引擎
这里是早起整理的myisam优势,因为当时刚毕业那会web1.0时代还没过时,很多的门户网站实际上就只是内容展示的时候,或者发布文章公告的场景.所以对于这样的读多写少的场景,大多数使用的还是myisa ...
- PM-数据治理中,常用的术语解释
1 指标 是表征和评价一项或多项经营活动业务绩效的指示.指标由指标名称和指标数值两部分组成,指标名称及其涵义体现指标在质和量方面的规定性,指标数值反映指标在具体对象在特定时间.空间.条件下的数量表现. ...
- 鱼与熊掌可以兼得,腾讯云推出COS on CDC对象存储服务
01 前言 在云计算时代,各个企业的信息基础设施都在进行云化转型,一时间,似乎万物皆可上云.但是在上云过程中,有不少客户遇到过这样的问题:有部分数据出于合规需求,需要在本地存储与处理,怎么办?一些数据 ...