动态规划的一个初步学习

啥叫动态规划

在我们写很多的题目时,常常可以用暴力枚举来写,缺点就是速度太慢了。如果我们用一个数组或者哈希表(虽然我还没学过哈希表)将之前暴力枚举的数据储存起来,当再一次枚举到这个数字的时候就直接调用数组或者哈希表里面的数据,这样就能节省很多时间。所以动态规划就是带数组记忆的递归,所以动态规划也往往叫做记忆化搜索

1.状态转移方程是啥:状态转移方程根据我的理解就是,可以根据前面的一维数组(或者二维数组)推出接下来的数组中的值,优点类似于数学里面的数列里面的递推公式,在动态规划里面比较核心的的就是想出其递推公式,想出来后题目也会变得通透的多。

做动态规划的五步骤

1.dp数组以及下标的含义。
2.递推公式。
3.dp数组的初始化。
4.遍历顺序。
5.打印dp数组

01背包问题

优化前:用一个二维数组来存放数据。优化后:用一个一维数组来存放数据(所以01背包也是由相对固定的模板的)

优化前:二维数组进行存储
首先根据5步曲来,分析一下dp数组的含义:下标为0到i之间的物品(不同的物品有着不同的价值),任取放进容量为j的背包里面,而dp数组的具体值就是放进去这个物品的最大价值。

递推公式不放物品dp[i-1][j];
                      放物品dp[i-1][j-wight[i]]+value[i];(这个value[i]就是i这个物品的价值,同时还要声明一下,这里其实还要做一下判断,看是否有超过背包的最大容量)

最终的模样:dp[i][j]=max(dp[i-1][j],dp[i-1][j-wight[i]]+value[i]);

dp数组的初始化:需要将第一个物品那一行给初始化,其他的都初始化为0.

优化后:使用滚动数组也就是使用一维数组来实现价值最大化   
形象一点就是将这个二维矩阵压缩,或者是将这个贴在一个圆柱上,每次进行到下一个物品的时候就将这个圆柱转一下就切换到下一个物品了。
含义:dp数组里面存放的依然是物品的价值,而下标就是和未优化前的二维数组中的j一样:容量为j的背包所能装的最大价值为dp[j];

递归公式:dp[j]=max(dp[j],dp[j-wight[i]]+value[i]); 这个就是相当于将前一个物品给拷贝过来一份,所以在这里的dp[j]就是相当于前一层的数据。

 列题

过河卒

 做动态规划最重要的就是推出其递推公式,一般很难想到,所以这里建议先在二维数组先写几个数,然后看看这些数之间有没有什么关系(数学归纳法:先写出来几个看看这些数字有啥关系,然后如果找到规律了就直接使用)
(该图来自b站up:LetsLearning)

写几个数字就能发现,在没有马的情况下二维数组中的每一个数的值都是由它的上面和左边加构成,所以通过这里就可以的得到递推公式;a[i][j]=a[i-1][j]+a[i][j-1]; 

接下来就是加上马的干扰,我们先将整个棋盘全部初始化为1(这样做的目的是为了将0行和0列初始化为1,方便接下来的操作),我们用一个方向数组(这个数组里面记载的是马的行走规则,集“日”字型走),用一个for循环将马走到的地方全部初始化为0,这样进行递推的时候就方便进行加,如果加上马的话就需要堆递推进行一点小改动,主要就是体现在第0行和第0列的改动,这个时候第0行和第0列的的递推公式就要改成    a[i][j]=a[i][j-1];    a[i][j]=a[i-1][j]; ,因为马做过的地方的左边和上面都不能走,如果马的这个地方为0,那么后面相加的时候也会为0,就不会对后面的造成影响。
代码如下(中间这些被注释掉的没有必要看,就是用来检查我有没有做对)(对了a数组要开long long类型的,不然有些数据会过不了)

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll a[35][35];
int n,m;
int x,y;
int dx[9]={0,-1,-2,-2,-1, 1, 2, 2,1};
int dy[9]={0,-2,-1, 1, 2,-2,-1, 1,2};
int main()
{
	//初始化为1
	cin>>n>>m>>x>>y;
	for(int i=0;i<=n;i++){
		for(int j=0;j<=m;j++){
			a[i][j]=1;
		}
	}
	//马的存在
for(int i=0;i<=8;i++){
	int tx=x+dx[i];
	int ty=y+dy[i];
	if(tx<0||tx>n||ty>m||ty<0)
	continue;
	else
	a[tx][ty]=0;
}
//检查二维数组
//	for(int i=0;i<=n;i++){
//		for(int j=0;j<=m;j++)
//		printf("%5d ",a[i][j]);
//		printf("\n");
//	}
//接下来就是递推公式
	for(int i=0;i<=n;i++){
		for(int j=0;j<=m;j++){
			if(i==0&&j==0)
			continue;
			if(a[i][j]==0)//这个点是马走过的,那这里的值就不能走,就应该为0,由于之前我们已经将马走过的地方赋值为0,所以是可以跳过的
			continue;
			if(i==0)
			a[i][j]=a[i][j-1];
			else if(j==0)
			a[i][j]=a[i-1][j];
			else
			a[i][j]=a[i-1][j]+a[i][j-1];
		}
	}
//检查二维数组
//	for(int i=0;i<=n;i++){
//		for(int j=0;j<=m;j++)
//		printf("%5d ",a[i][j]);
//		printf("\n");
//	}
	cout<<a[n][m]<<endl;
	return 0;	
}

守望者的逃离

思路:先讲一遍不用动态规划来写的方法,我么用一个s1和s2分别代表着不用闪现走的路程,和用闪现走的路程,两边同时开弓。每次进行完一次计算都需要将s1和s2进行一次比较将大者的值赋给s1(由于s1是最特殊的,最后我们输出的变量的值也是s1的值)(其实使用动态规划也是使用这样一个思路)其中这里面很巧妙的思路就是使用一个for循环来代表时间的推进还有使用s1,s2两边同时开工,然后这个路程的取值往往都是取最大(我还没学过贪心)。

代码如下:

#include<iostream>
using namespace std;
int m,s,t;
int main()
{
	cin>>m>>s>>t;
	int s1=0,s2=0;
	for(int i=1;i<=t;i++)
	{
		s1+=17;
		if(m>=10){
			s2+=60;
			m-=10;
		}
		else{
			m+=4;
		}
		if(s2>s1)s1=s2;
		if(s1>=s){
			cout<<"Yes"<<endl;
			cout<<i<<endl;
			return 0;
		}
	}
	cout<<"No"<<endl;
	cout<<s1<<endl;
	return 0;
}

接下就是讲解使用dp数组求解:
思路:和上面的思路其实一样,在这里我感觉到动态规划就是要使用前一个数组元素的值来进行求解(及最关键的就是看大问题是否能够被小问题推出,如果已经看出来这一点那么递推公式也就能写出来了),先将dp数组全部用闪现的方式记录每一秒的运动路程。在进行完全部过程后再使用一个for循环来检查就用看是dp[i]大还是dp[i-1]+17大,如果是后者大那么就将这个值赋给dp[i](我怎么感觉有一点01背包的思想在里面).

#include<iostream>
using namespace std;
int dp[500000000];
int main()
{
	int m,s,t;
	cin>>m>>s>>t;
	for(int i=1;i<=t;i++)
	{
		if(m>=10)
		{
			dp[i]=dp[i-1]+60;
			m-=10;
		}
		else
		{
			dp[i]=dp[i-1];
			m+=4;
		}
	}
	for(int i=1;i<=t;i++)
	{
		if(dp[i]<dp[i-1]+17)
		dp[i]=dp[i-1]+17;
		if(dp[i]>=s)
		{
			printf("Yes\n%d",i);
			return 0;
		}
	}
	printf("No\n%d",dp[t]);
	return 0;
}


 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用vue-client-only 解决组件不兼容SSR问题

目录 前言 一、解决方案 1.基于Nuxt 框架的SSR应用 2.基于vue2框架的应用 3.基于vue3框架的应用 二、总结 往期回顾 前言 最近在我的单页面SSR应用上开发JSON编辑器功能&#xff0c;在引入组件后直接客户端跳转OK&#xff0c;但是在直接加载服务端渲染的时候一直报这…

并发容器(Map、List、Set)实战及其原理

目录 JUC包下的并发容器 CopyOnWriteArrayList 应用场景 CopyOnWriteArrayList使用 CopyOnWriteArrayList原理 CopyOnWriteArrayList 的缺陷 扩展知识&#xff1a;迭代器的 fail-fast 与 fail-safe 机制 ConcurrentHashMap 应用场景 ConcurrentHashMap使用 数…

阿里云幻兽帕鲁服务器免费搭建解决方法,白嫖阿里云

阿里云幻兽帕鲁服务器免费搭建方案&#xff0c;先在阿里云高校计划「云工开物」活动领取学生专享300元无门槛代金券&#xff0c;幻兽帕鲁专用服务器4核16G配置26元1个月、149元半年&#xff0c;直接使用这个无门槛300元代金券抵扣即可免费搭建幻兽帕鲁服务器。阿里云服务器网al…

2.8日学习打卡----初学RabbitMQ(三)

2.8日学习打卡 一.springboot整合RabbitMQ 之前我们使用原生JAVA操作RabbitMQ较为繁琐&#xff0c;接下来我们使用 SpringBoot整合RabbitMQ&#xff0c;简化代码编写 创建SpringBoot项目&#xff0c;引入RabbitMQ起步依赖 <!-- RabbitMQ起步依赖 --> <dependency&g…

小游戏和GUI编程(3) | 基于 SFML 的字符阵

小游戏和GUI编程(3) | 基于 SFML 的字符阵 1. 简介 使用 EasyX 图形库时&#xff0c; 官方第一个例子是字符阵。 EasyX 不开源&#xff0c; 也不能跨平台&#xff0c; API 陈旧&#xff0c; API 是 C 而不是 C。 现在使用 SFML 来实现字符阵&#xff0c; 克服 EasyX 的这些问…

OCP使用CLI创建和构建应用

文章目录 环境登录创建project赋予查看权限部署第一个image创建route检查pod扩展应用 部署一个Python应用连接数据库创建secret加载数据并显示国家公园地图 清理参考 环境 RHEL 9.3Red Hat OpenShift Local 2.32 登录 通过 crc console --credentials 可以查看登录信息&…

动态内存管理(下)

1.常见的动态内存的错误 我们在学习动态内存的时候&#xff0c;常出现的一些错误我们来看一下。 1.对NULL指针的解引用操作 例如我们在使用malloc或者calloc开辟动态空间的时候&#xff0c;有时候没有判断是否开辟成功而直接对齐的返回指针进行解引用&#xff0c;此时如果开…

[论文总结] 深度学习在农业领域应用论文笔记12

文章目录 1. 3D-ZeF: A 3D Zebrafish Tracking Benchmark Dataset (CVPR, 2020)摘要背景相关研究所提出的数据集方法和结果个人总结 2. Automated flower classification over a large number of classes (Computer Vision, Graphics & Image Processing, 2008)摘要背景分割…

基于图像掩膜和深度学习的花生豆分拣(附源码)

目录 项目介绍 图像分类网络构建 处理花生豆图片完成预测 项目介绍 这是一个使用图像掩膜技术和深度学习技术实现的一个花生豆分拣系统 我们有大量的花生豆图片&#xff0c;并以及打好了标签&#xff0c;可以看一下目录结构和几张具体的图片 同时我们也有几张大的图片&…

Java强训day16(选择题编程题)

选择题 编程题 题目1 import java.util.Scanner;public class Main { public static boolean res(int m) {int sum 0;for(int i1;i<m;i) {if(i!m && m%i 0) {sumi;}}if(sum m)return true;elsereturn false;}public static void main(String[] args) {Scanne…

js手写Promise(上)

目录 构造函数resolve与reject状态改变状态改变后就无法再次改变 代码优化回调函数中抛出错误 thenonFulfilled和onRejected的调用时机异步then多个then 如果是不知道或者对Promise不熟悉的铁铁可以先看我这篇文章 Promise 构造函数 在最开始&#xff0c;我们先不去考虑Promi…

FFmpeg中的Color颜色参数解析、转码和HDR

前言 视频中帧的颜色信息非常重要&#xff0c;表示着编码时用到的标准&#xff0c;意味着解码时也要对应上&#xff0c;或者要使用正确的转换函数&#xff0c;否则就会带来色差问题。 关于FFmpeg中的颜色参数&#xff0c;有下边几个重要的结构体&#xff1a; 颜色参数相关的结…

Git远程仓库的使用(Gitee)及相关指令

目录 1 远程仓库的创建和配置 1.1 创建远程仓库 1.2 设置SSH公钥 2 指令 2.1 git remote add 远端名称(一般为origin) 仓库路径 2.2 git remote 2.3 git push [-f] [--set-upstream] [远端名称 [本地分支名][:远端分支名]] 2.3 git clone url 2.4 git fetch 2.5 git p…

巴尔加瓦算法图解:算法运用(上)

目录 树反向索引傅立叶变换 并行算法MapReduce函数 树 如果能将用户名插入到数组的正确位置就好了&#xff0c;这样就无需在插入后再排序。为此&#xff0c;有人设计了一种名为二叉查找树(binary search tree)的数据结构。 每个node的children 都不大于两个。对于其中的每个…

微信小程序上传代码教程

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 小程序上传代码到gogs上面来 整体架构流程 小程序也要远程连接仓库&#xff0c;实现代码上传 技术名词解释 微信开发者工具gogs 技术细节 连接gogs仓库地址 微信小程序需要head将本地代码和gogs代码同步 小结 …

java学习(多态)

一、多态 含义&#xff1a;方法或对象具有多种形态。是面向对象的第三大特征&#xff0c;多态是建立在封装和继承基础上的。 多态的具体体现&#xff1a; 1&#xff09;方法的多态 &#xff08;例如重写和重载&#xff09; 2&#xff09;对象的多态 多态注意事项&#xff1…

SpringCloud--Gateway解析

一、Gateway简介 Gateway是Spring Cloud官方推出的第二代微服务网关&#xff0c;它旨在提供统一的路由方式以及为微服务应用提供强大的负载均衡能力。与第一代Spring Cloud Netflix Zuul相比&#xff0c;Spring Cloud Gateway在性能、可扩展性、易用性等方面都有了显著的提升。…

python web 框架Django学习笔记

2018年5月 python web 框架Django学习笔记 Django 架站的16堂课 MVC架构设计师大部分框架或大型程序项目中一种软件工程的架构模式&#xff0c;把程序或者项目分为三个主要组成部分&#xff0c;Model数据模型、View视图、Controller控制器。 命令及设置相关 创建数据库及中间…

使用Launch4j将jar包转成.exe可执行文件

Launch4j官网:Launch4j - Cross-platform Java executable wrapper 然后点击上面按钮 随便写个文件名

分享66个相册特效,总有一款适合您

分享66个相册特效&#xff0c;总有一款适合您 66个相册特效下载链接&#xff1a;https://pan.baidu.com/s/1jqctaho4sL_iGSNExhWB6A?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不…
最新文章