NOI Newnode模拟题 第二题 DP 单调性优化 三分法

2023-10-05 13:59

本文主要是介绍NOI Newnode模拟题 第二题 DP 单调性优化 三分法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第二题

【问题描述】

小火车虽然很穷,但是他还是得送礼物给妹子,所以他前往了二次元寻找不需要钱的礼物。小火车准备玩玩二次元的游戏,游戏当然是在一个二维网格中展开的,网格大小是n*m的,某些格子是好的,其余的则是不好的。每次你可以选择最底层(也就是第n层)的某两个相邻的列,并消掉最底下的至多三个格子,并且这两列都得有格子被消掉(也就是L型或者反着的L型),消掉格子以后上面的格子会掉落下来。当然最上面的空位会用不好的格子填满。小火车想得到所有的好格子送给妹子,请问至少得消多少次呢?

【输入格式】

第一行两个整数n,m,表示网格大小。接下来n行每行一个长度为m的字符串,表示这个网格,如果为*则是好格子,为#就不是。

【输出格式】

一行一个整数表示答案。

【数据范围与约定】

对于20%的数据n,m<=5;
对于50%的数据满足n,m<=500;
对于100%的数据满足2<=n,m<=2000。


首先容易想到把原题目转化为:用两种L把每一列的最上面的*消掉,求至少消多少次。

进一步转化:
把每一列最上面的*的位置写成一个数列 A[i] A [ i ] ,每次操作可以使得数列里相邻的两个数其中一个减去1,另一个减去2.求把这个数列中全部数字变为非正数的最小操作数。

结合数据范围,不难想到采用DP的方式解决。

由于每一个元素的消去,只与在自己和左右两边相邻的元素上进行的操作有关,那么定义 f[i][j] f [ i ] [ j ] 为已经将 i1 i − 1 及以前的所有数字变为非正数,且第 i i 列目前的数字是j的最小操作数。那么目前只需要考虑在消去 i i 位上的数字时对第i+1位的影响就可以转移了。

预处理一个数组 g[i][j] g [ i ] [ j ] ,表示把两个数字 i,j i , j 消去的最小操作数。那么有:

f[i+1][j]=min{f[i][k]+g[A[i+1]j][k]} f [ i + 1 ] [ j ] = m i n { f [ i ] [ k ] + g [ A [ i + 1 ] − j ] [ k ] }

其中 g[i][j] g [ i ] [ j ] 可以 O(n2) O ( n 2 ) 预处理:
g[i][j]=min{g[i2][j1],g[i1][j2],g[i1][j1]}+1 g [ i ] [ j ] = m i n { g [ i − 2 ] [ j − 1 ] , g [ i − 1 ] [ j − 2 ] , g [ i − 1 ] [ j − 1 ] } + 1

然后发现弄出 f f 的时间复杂度是O(n3)的,考虑优化这个DP。

考虑 f,g f , g 各有什么性质。对于 g g ,根据其含义,显然有:

g[i][j+1]g[i][j]

对于 f f ,有:
f[i][j]f[i][j+1]

也比较显然,剩得越多,消的次数肯定不会更多嘛。

回过头来看DP方程:

f[i+1][j]=min{f[i][k]+g[A[i+1]j][k]} f [ i + 1 ] [ j ] = m i n { f [ i ] [ k ] + g [ A [ i + 1 ] − j ] [ k ] }

枚举 i,j i , j 显然是无法优化的,要优化就要考虑优化枚举 k k .根据上面的分析,注意到在k不断增大的过程中, f[i][k] f [ i ] [ k ] 单调不升,而 g[A[i+1]j][k] g [ A [ i + 1 ] − j ] [ k ] 单调不减,那么 f[i][k]+g[A[i+1]j][k] f [ i ] [ k ] + g [ A [ i + 1 ] − j ] [ k ] 就是一个关于 k k 的单峰函数!单峰函数的极值可以用三分法处理。

整数的三分好像不是很好……我采用的是在rl小于一定值之后暴力更新答案。采用三分法的话,这个值给得小就会错。

有不用三分的优秀做法:http://blog.csdn.net/Mogician_Evian/article/details/79474362


代码写得比较丑。

#include<stdio.h>
#include<cstring>
#include<algorithm>
#define MAXN 2005
using namespace std;int N,M,A[MAXN],f[MAXN][MAXN],g[MAXN][MAXN];
char Map[MAXN][MAXN];int main(){int i,j,k,l,r,lmid,rmid,t,id;scanf("%d%d",&N,&M);for(i=1;i<=N;i++)scanf("%s",&Map[i][1]);for(i=1;i<=M;i++){for(j=1;j<=N;j++)if(Map[j][i]=='*'){A[i]=N-j+1;break;}}memset(g,60,sizeof(g));memset(f,60,sizeof(f));g[0][0]=0;for(i=1;i<=N;i++)g[i][0]=g[0][i]=(i+1)/2;for(i=1;i<=N;i++)for(j=1;j<=N;j++){if(i>1)g[i][j]=min(g[i][j],g[i-2][j-1]+1);if(j>1)g[i][j]=min(g[i][j],g[i-1][j-2]+1);g[i][j]=min(g[i][j],g[i-1][j-1]+1);}f[1][A[1]]=0;for(i=1;i<=M;i++){if(i==1){for(j=0;j<=A[i+1];j++)for(k=0;k<=A[i];k++)f[i+1][j]=min(f[i+1][j],f[i][k]+g[A[i+1]-j][k]);continue;}for(j=0;j<=A[i+1];j++){l=0;r=A[i];while(l<=r){if(r-l<=25){for(k=l;k<=r;k++)f[i+1][j]=min(f[i+1][j],f[i][k]+g[A[i+1]-j][k]);break;}lmid=(r-l)/3+l;rmid=(r-l)/3+lmid;if(f[i][lmid]+g[A[i+1]-j][lmid]<f[i][rmid]+g[A[i+1]-j][rmid])r=rmid;else if(f[i][lmid]+g[A[i+1]-j][lmid]>f[i][rmid]+g[A[i+1]-j][rmid])l=lmid;else l=lmid,r=rmid;}}}printf("%d\n",f[M+1][0]);
}

这篇关于NOI Newnode模拟题 第二题 DP 单调性优化 三分法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/151328

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传