dp专题(二)

news2024/11/23 18:45:30

洛谷:B3626 跳跃机器人

题目描述

地上有一排格子,共 nn 个位置。机器猫站在第一个格子上,需要取第 nn 个格子里的东西。

机器猫当然不愿意自己跑过去,所以机器猫从口袋里掏出了一个机器人!这个机器人的行动遵循下面的规则:

  • 初始时,机器人位于 11 号格子
  • 若机器人目前在 xx 格子,那么它可以跳跃到 x−1,x+1,2xx−1,x+1,2x 里的一个格子(不允许跳出界)

问机器人最少需要多少次跳跃,才能到达 nn 号格子。

输入格式

仅一行,一个正整数,表示 nn。

输出格式

仅一行,一个正整数,表示最少跳跃次数。

输入 #1复制

30

输出 #1复制

6

输入 #2复制

50

输出 #2复制

7

输入 #3复制

64

输出 #3复制

6

输入 #4复制

63

输出 #4复制

8
样例解释

第一组样例:
1→2→4→8→16→15→301→2→4→8→16→15→30

第二组样例:
1→2→3→6→12→24→25→501→2→3→6→12→24→25→50

第三组样例:
1→2→4→8→16→32→641→2→4→8→16→32→64

第四组样例:
1→2→4→8→16→32→31→62→631→2→4→8→16→32→31→62→63

请注意在本组样例中,6363 不能通过 64−164−1 得到,因为格子总数为 6363,没有第 6464 个格子。

数据规模与约定

对于 100%100% 的数据,有 1≤n≤10000001≤n≤1000000。

做法

dp数组 下标:第i格 ; 值:步数

感觉有点递推关系的都可以考虑一下dp

#include<bits/stdc++.h>
using namespace std;
int n;
int dp[1000010];
int main(){

	scanf("%d",&n);
	memset(dp,0x3f,sizeof(dp));
	dp[1]=0;

	for(int i=2;i<=n;i++){

		dp[i]=dp[i-1]+1;

		if(i%2==0){
			dp[i]=min(dp[i],dp[i/2]+1);
			dp[i-1]=min(dp[i-1],dp[i]+1);
		}

	}

	cout<<dp[n];
}

2024黑龙江省赛:J. Trade

题目

在一个繁荣的国家,金斯诺决定从事贸易。

这个国家由 𝑛∗𝑚n∗m 座城市组成。每个城市由一对整数 (𝑥,𝑦)(x,y) 表示,其中 1≤𝑥≤𝑛1≤x≤n 和 1≤𝑦≤𝑚1≤y≤m 表示其在网格中的位置。在城市 (𝑥,𝑦)(x,y) 中,物品的价格用 𝑎[𝑥][𝑦]a[x][y] 表示,到达该城市的旅行费用用 𝑏[𝑥][𝑦]b[x][y] 表示。

在踏上旅程之前,金斯诺需要你为他规划一条路线。路线必须符合以下条件:

  • 路线的起点必须是位于第一行第一列的城市,即 (1,1)(1,1) 。
  • 路线的终点必须是位于最后一行( 𝑥=𝑛x=n )或最后一列( 𝑦=𝑚y=m )的城市。
  • 金斯诺只能从城市 (𝑥𝑖,𝑦𝑖)(xi,yi) 移动到 (𝑥𝑖+1,𝑦𝑖)(xi+1,yi) 或 (𝑥𝑖,𝑦𝑖+1)(xi,yi+1) 。因此,对于路线中的每一步 𝑖i (路线中的最后一步除外), (𝑥𝑖+1,𝑦𝑖+1)(xi+1,yi+1) 必须选择在 (𝑥𝑖,𝑦𝑖)(xi,yi) 的正下方或正右方。

进入路线后,Kingsnow 将在路线的第一个城市 (1,1)(1,1) 购买一件物品。然后,他将任意选择路线上的另一个城市出售该物品。此外,从他开始旅行的城市到他出售物品的城市之间,每到一个城市,他都会支付旅行费用。

也就是说,对于任何给定的路线 (𝑥1,𝑦1),(𝑥2,𝑦2),...,(𝑥𝑘,𝑦𝑘)(x1,y1),(x2,y2),...,(xk,yk) ,Kingsnow 都会从区间 [2,𝑘][2,k] 中任意选择一个整数 𝑡t 。他在城市 (𝑥𝑡,𝑦𝑡)(xt,yt) 出售商品的利润计算公式为 Profit=𝑎[𝑥𝑡][𝑦𝑡]−𝑎[1][1]−∑𝑡𝑖=1𝑏[𝑥𝑖][𝑦𝑖]Profit=a[xt][yt]−a[1][1]−∑i=1tb[xi][yi]

金斯诺寻找的路线是,无论他选择在路线上的哪个城市出售物品,他都能获得非负利润。

输入

第一行包含两个整数 𝑛n 和 𝑚(1≤𝑛,𝑚≤1000)m(1≤n,m≤1000) - 行数和列数。确保 𝑛n 和 𝑚m 不同时等于 11 。

在接下来的 𝑛n 行中,每一行都包含范围为 [1,109][1,109] 的 𝑚m 个整数,表示物品在每个城市的价格。第 𝑥x 行中的第 𝑦y 个整数是 𝑎[𝑥][𝑦]a[x][y] 。

在接下来的 𝑛n 行中,每一行都包含 𝑚m 个整数,范围为 [1,109][1,109] ,表示每个城市的差旅费用。第 𝑥x 行中的第 𝑦y 个整数是 𝑏[𝑥][𝑦]b[x][y] 。

输出

如果至少有一条路由符合要求,则输出 "是",否则输出 "否"。

做法

dp数组 下标:位于i行j列  ; 值:旅行费用

#include<bits/stdc++.h>
using namespace std;

int n,m;
long long a[1010][1010],b[1010][1010],dp[1010][1010];

int main(){

	scanf("%d%d",&n,&m);
	memset(dp,0x3f3f3f3f3f3f3f3f,sizeof(dp));

	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%lld",&a[i][j]);
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%lld",&b[i][j]);
		}
	}
	
	dp[1][0]=dp[0][1]=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]-a[1][1]-dp[i-1][j]>=0) dp[i][j]=min(dp[i-1][j]+b[i][j],dp[i][j]);
			if(a[i][j]-a[1][1]-dp[i][j-1]>=0) dp[i][j]=min(dp[i][j-1]+b[i][j],dp[i][j]);
		}
	}
	
	if(dp[n][m-1]!=0x3f3f3f3f3f3f3f3f||dp[n-1][m]!=0x3f3f3f3f3f3f3f3f) cout<<"YES";
	else cout<<"NO";
}

牛客小白月赛95:E.相依

题目描述

此题为C题的hard版,只有aia_iai​的数据范围不同。

给你一个 nnn 个正整数组成的数组 a ,你每次操作可以选择一对 (i,j)( i, j )(i,j),满足 1≤i<j≤n1 \leq i < j \leq n1≤i<j≤n,且 ai=aja_{i} = a_{j}ai​=aj​ ,将 { ai,ai+1,...,aj−1,aja_{i} , a_{i+1} , ... , a_{j-1} , a_{j}ai​,ai+1​,...,aj−1​,aj​ } 这段数删除,操作之后数组变为 { a1,a2,...,ai−1,aj+1,...,an−1,ana_{1},a_{2}, ..., a_{i-1},a_{j+1}, ...,a_{n-1},a_{n}a1​,a2​,...,ai−1​,aj+1​,...,an−1​,an​ }。文文想知道最少要做多少次操作才能将数组变为空。

输入描述:

第一行一个正整数输入 nnn (1≤n≤5×105)( 1 \leq n \leq 5 \times 10^5 )(1≤n≤5×105)。

第二行依次输入 nnn 个正整数 a1,a2,...,an−1,ana_{1},a_{2},...,a_{n-1},a_{n}a1​,a2​,...,an−1​,an​,每个数之间以空格分开。(0≤ai≤n)( 0 \leq a_i \leq n )(0≤ai​≤n)

输出描述:

输出一行,代表最少的操作次数,如果无论如何都无法使数组为空就输出 -1。

示例1

输入

5
3 2 3 2 2

输出

2

说明

例如,n 为 5,数组为{3,2,3,2,2}\{3, 2, 3, 2, 2\}{3,2,3,2,2},第一次操作我们可以选择 i=1i = 1i=1,j=3j = 3j=3,把这一段删除后数组变为 {2,2}\{2, 2\}{2,2},第二次操作我们可以选择 i=1i = 1i=1,j=2j = 2j=2,把这一段删除后数组变为空,操作了两次。

示例2

输入

5
1 2 3 4 5

输出

-1

做法

dp数组  下标:消除前i个   ;  值:最小操作次数

这题一开始我在怀疑dp的正确性,然后举了几个样例发现他确实能完美解决,还挺神奇的。只能说以后尽量往这个方向靠了,太难想了。

不过最值是一个标志。

//O(n^2)做法
#include<bits/stdc++.h>
using namespace std;
int n;
int a[500010],dp[500010];
int main(){

    memset(dp,0x3f,sizeof(dp));
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }

    dp[0]=0;

    for(int i=1;i<=n;i++){

        for(int j=1;j<i;j++){

            if(a[i]==a[j]){//找前面和当前数字相同的且操作数最小的
                dp[i]=min(dp[i],1+dp[j-1]);
            }

        }

    }

    if(dp[n]==0x3f3f3f3f) cout<<-1;
    else cout<<dp[n]; 
}


//O(n)做法
#include<bits/stdc++.h>
using namespace std;

int n;
int a[500010],dp[500010],minn[500010];

int main(){

    memset(dp,0x3f,sizeof(dp));
    memset(minn,0x3f,sizeof(dp));
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }

    dp[0]=0;
    
    for(int i=1;i<=n;i++){

        dp[i]=minn[a[i]];//前面和当前数字相同的且操作数最小的可以用数组minn来维护,实现降低复杂度
        minn[a[i]]=min(minn[a[i]],dp[i-1]+1);

    }

    if(dp[n]!=0x3f3f3f3f) cout<<dp[n];
    else cout<<-1; 

}

2024河南省赛:L-Toxel 与 PCPC II

做法

dp数组  考虑了第i个bug ,解决了j个bug  ; 值:需要的时间 

有时候用滚动数组也会超时,直接降维就好了。

这题的关键在于:如果连续修复太多个bug的话这个数得四次方是远大于从头开始扫描的时间,22的四次方刚好是大于2e5最小整数,所以就可以利用这点降低复杂度。

//最开始的思路
#include<bits/stdc++.h>
using namespace std;

int n,m;
long long a[200010],dp[2010][2010];

int main(){
	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%lld",&a[i]);
	for(int i=0;i<=m;i++){
		for(int j=0;j<=m;j++){
			dp[i][j]=0x3f3f3f3f3f3f3f3f;
		}
	}
	
	sort(a+1,a+1+m);
	dp[0][0]=0;
	
	for(int i=1;i<=m;i++){
		
		int j=0;
		if(i-j>22) j=i-21;
		
		for(;j<=i;j++){
			
			if(j==0) dp[i][j]=0;//一个都不解决 
			
			else if(i!=j) dp[i][j]=min(dp[i][j],dp[j][j]);//只解决了前j个不解决 
			
			if(i==j){//全部都解决了
			 
				int k=0;
				if(j-k>22) k=j-22;
				
				for(;k<j;k++){//i个问题解决了k个 
				
					if(k==0) dp[i][j]=min(dp[i][j],a[i]+1ll*i*i*i*i);//一次性解决 
					
					else dp[i][j]=min(dp[i][j],a[i]+1ll*(i-k)*(i-k)*(i-k)*(i-k)+dp[k][k]);//已经解决了前k个 
					
				}
				
			}
			
		}

	}
	
	cout<<dp[m][m];
	
}


//可以看到,数组开不下,用滚动数组也会超时。但我们可以发现,这题直接降维就好了,因为大的值由小的覆盖,不用担心上层和这层乱赋值的情况。
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long a[200010],dp[200010];
int main(){
	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%lld",&a[i]);
	for(int j=0;j<=m;j++){
		dp[j]=0x3f3f3f3f3f3f3f3f;
	}
	
	sort(a+1,a+1+m);
	dp[0]=0;
	
	for(int i=1;i<=m;i++){
		
		int j=0;
		if(i-j>22) j=i-21;
		
		for(;j<=i;j++){
			
			
			
			if(j==0) dp[j]=0;//不解决 
			
			else if(i!=j) dp[j]=min(dp[j],dp[j]);
			
			if(i==j){
				
				int k=0;
				if(j-k>22) k=j-21;
				
				for(;k<j;k++){
					
					if(k==0) dp[j]=min(dp[j],a[i]+1ll*i*i*i*i);
					
					else dp[j]=min(dp[j],a[i]+1ll*(i-k)*(i-k)*(i-k)*(i-k)+dp[k]);
					
				}
				
			}
	
		}

	}
	
	cout<<dp[m];
	
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1973700.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【面试题】【C语言】寻找两个正序数组的中位数

寻找两个正序数组的中位数 仅供学习 题目 算法时间复杂度 二分查找算法&#xff0c;时间复杂度为 O(log(min(m, n)))&#xff0c;其中 m 和 n 分别是两个数组的长度。 子函数 查找两个数字的最大值 int max(int a, int b) {return a > b ? a : b; }查找两个数字的最小…

ubuntu20.04搭建RUST开发环境并与C语言交互

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 ubuntu20.04搭建RUST开发环境并与C语言交互 前言开战一、确认环境版本二、环境搭建三、hello world&#xff01;四、跟c语言进行交互1.rust调用C静态库2.C调用rust库 总结参考…

LDR6500:小封装,易设计外围简单OTG数据+充电实现原理

移动设备的普及与功能日益丰富的今天&#xff0c;OTG&#xff08;USB On-The-Go&#xff09;转接器作为连接移动设备与外部设备的桥梁&#xff0c;其重要性不言而喻。而LDR6500&#xff0c;作为乐得瑞科技精心打造的一款USB-C DRP&#xff08;Dual Role Port&#xff0c;双角色…

vue3修改带小数点的价格数字:小数点的前后数字,要分别显示成不同颜色和大小!已经封装成组件了!

需求&#xff1a; 修改带小数点的价格数字&#xff1a;小数点的前后数字&#xff0c;要分别显示成不同颜色和大小&#xff01;已经封装成组件了&#xff01; 效果&#xff1a; 前面大&#xff0c;后面小 代码&#xff1a; 组件&#xff1a; <!--修改小数点前后数字不同…

nodejs多版本随心切换-windows

nodejs多版本控制 1. 安装 nvm github下载地址 不需要卸载已安装的nodejs&#xff0c;安装时会让你选择nodejs的位置&#xff0c;可修改为你已经安装的路径&#xff0c;会自动搜索已安装版本&#xff0c;并进行弹窗询问&#xff0c;选择托管即可 2. 修改配置文件 在 nvm 安装…

全网最适合入门的面向对象编程教程:30 Python的内置数据类型-object根类

全网最适合入门的面向对象编程教程&#xff1a;30 Python 的内置数据类型-object 根类 摘要&#xff1a; 在 Python 中&#xff0c;所有的类都直接或间接继承自一个根类&#xff0c;这个根类是Object。Object类是 Python 中所有新式类的基础类&#xff0c;在 Python 的类层次结…

Docker安装Nacos及动态配置

文章目录 1.安装Nacos1.拉取镜像2.启动Nacos3.开启8848和9848端口1.88482.9848 4.访问nacos1.网址 http://guest:8848/nacos/ 2.Nacos动态配置&#xff08;无法实现bean动态加载&#xff09;1.新建一个配置&#xff0c;使其成为动态的2.引入Nacos依赖3.application.yml配置Naco…

常见病症之中医药草马齿苋

常见病症之中医药草马齿苋 1. 源由2. 马齿苋植物描述药用部分主要成分药理作用使用方法注意事项 2. 常用方剂2.1 马齿苋汤2.2 马齿苋粥 3. 马齿苋的奇效具体应用实例 4. 湿疹方剂4.1 常见方剂内服方剂加减调整外用方剂 4.2 加“马齿苋”内服方剂加减调整外用方剂 4.3 注意事项 …

【Spring Boot】配置 Spring Security

配置 Spring Security 1.继承 WebSecurityConfigurerAdapter2.配置自定义策略3.配置加密方式3.1 BCrypt 加密 4.自定义加密规则5.配置多用户系统5.1 构建 UserDetailsService 用户信息服务接口5.2 进行安全配置 6.获取当前登录用户信息的几种方式6.1 在 Thymeleaf 视图中获取6.…

第23集《大佛顶首楞严经》

请大家打开讲义第五十二页&#xff0c;癸八&#xff0c;约外道世谛对简显见性非因缘自然。 本经的修学特色&#xff0c;简单地讲&#xff0c;它是在处理生命的根本问题。就是当我们在行菩萨道的时候&#xff0c;我们会去布施、持戒、忍辱或者是禅定&#xff0c;在整个修学当中…

centos 8.5时间设置

编辑 chrony 配置文件 vim /etc/chrony.conf新增内容&#xff1a; server 210.72.145.44 iburst server ntp.aliyun.com iburst同时要注释一下&#xff1a;# pool 2.centos.pool.ntp.org iburst 重启chronydf服务 systemctl restart chronyd.service设置 chronyd 开机自启…

谷粒商城实战笔记-118-全文检索-ElasticSearch-进阶-aggregations聚合分析

文章目录 一&#xff0c;基本概念主要聚合类型 二&#xff0c;实战1&#xff0c;搜索 address 中包含 mill 的所有人的年龄分布以及平均年龄&#xff0c;但不显示这些人的详情2&#xff0c;按照年龄聚合&#xff0c;并且请求每个年龄的平均薪资 Elasticsearch 的聚合&#xff0…

大屏宁德烟草第二版总结,批量导入

toFixed toFixed(x) 方法返回一个表示 numObj 的字符串&#xff0c;如果不该x&#xff0c;会进行四舍五入。 includes() includes() 方法用来判断一个数组是否包含一个指定的值&#xff0c;根据情况&#xff0c;如果包含则返回 true&#xff0c;否则返回 false。 批量导入…

饿了吗新版bxet

声明(lianxi a15018601872) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言(…

【Linux】网络编程_3

文章目录 十、网络基础5. socket编程socket 常见APIsockaddr结构简单的UDP网络程序 未完待续 十、网络基础 5. socket编程 socket 常见API // 创建 socket 文件描述符 (TCP/UDP, 客户端 服务器) int socket(int domain, int type, int protocol);// 绑定端口号 (TCP/UDP, 服…

LLM大模型的书那么多,如何快速选到适合自己的那一本?来,我教你!

大模型的书这么多&#xff0c;该怎么选呢&#xff1f;今天就来教大家怎么快速地从众多大模型书中选到你想要的那一本&#xff01; 朋友们如果有需要这些大模型书 扫码获取~ &#x1f449;CSDN大礼包&#x1f381;&#xff1a;全网最全《LLM大模型书籍资源包》免费分享&#xf…

SpringBoot入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享

场景 作为一名Java开发者&#xff0c;SpringBoot已经成为日常开发所必须。 势必经历过从入门到自学、从基础到进阶、从学习到强化的过程。 当经历过几年企业级开发的磨炼&#xff0c;再回头看之前的开发过程、成长阶段发现确实是走了好多的弯路。 作为一名终身学习的信奉者…

程序工具_doxygen

doxygen是API文档生成工具 安装和使用&#xff1a; 下载地址&#xff1a;https://www.doxygen.nl/download.html 安装一直next就可以。 打开后的界面&#xff1a; 使用&#xff1a; 选择好文件夹&#xff0c;然后 “Run dexygen”&#xff0c;就在选择的文件夹下生成html和…

浏览器用户文件夹详解 - WebData(八)

1.WebData简介 1.1 什么是WebData文件&#xff1f; WebData文件是Chromium浏览器中用于存储用户表单数据、自动填充信息和支付信息的一个重要文件。每当用户在浏览器中填写表单或保存支付信息时&#xff0c;这些数据都会被记录在WebData文件中。通过这些记录&#xff0c;浏览…

[PM]面试题-综合问题

思维题 说说当前的科技行业 web3是我比较感兴趣的方向, 在国内还处于起步阶段, web3重要的特点是去中心化, 依赖的技术有以太坊, 区块链, 智能合约, 现在位置还没有特别成熟的产品形态, 发展的比较好的方向就是数字藏品和游戏方向 列举一个你认为比较好的APP, 说明其独特之处…