算法基础精选题单 动态规划(dp)(递推+线性dp)(个人题解)

前言:

  一些简单的dp问题。

正文:

题单:237题】算法基础精选题单_ACM竞赛_ACM/CSP/ICPC/CCPC/比赛经验/题解/资讯_牛客竞赛OJ_牛客网 (nowcoder.com)

递推:

NC235911 走楼梯:

#include<bits/stdc++.h>
using namespace std;
long long dp[150];
int main(){
	int n;
	cin>>n;
	dp[1]=1;dp[0]=1;
	for(int i=2;i<=n;i++){
		dp[i]=dp[i-1]+dp[i-2];
	}
	cout<<dp[n];
	return 0;
}

dp中最经典的问题,就不展开说了。

线性dp:

NC22096 数字三角形:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	while(cin>>n){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=i;j++){
			cout<<j<<" ";
		}
		cout<<endl;
	}}
	return 0;
} 

这题不知道和dp有什么关系,直接两层循环输出就行了。

NC16708 过河卒:

#include<bits/stdc++.h>
using namespace std;
long long dp[55][55];
void con(int x,int y){
	dp[x][y]=-1;
	if(x+1>=0&&y+2>=0)dp[x+2][y+1]=-1;
	if(x+2>=0&&y+1>=0)dp[x+1][y+2]=-1;
	if(x+2>=0&&y+1>=0)dp[x-1][y+2]=-1;
	if(x-2>=0&&y+1>=0)dp[x-2][y+1]=-1;
	if(x-2>=0&&y-1>=0)dp[x-2][y-1]=-1;
	if(x-1>=0&&y-2>=0)dp[x-1][y-2]=-1;
	if(x+1>=0&&y-2>=0)dp[x+1][y-2]=-1;
	if(x+2>=0&&y-1>=0)dp[x+2][y-1]=-1;
}
int main(){
	int n,m,x,y;
	cin>>n>>m>>x>>y;
	con(x+1,y+1);
	dp[1][1]=1;
	for(int i=1;i<=21;i++){
		for(int j=1;j<=21;j++){
			if(dp[i][j]!=-1){
				if(dp[i-1][j]!=-1)dp[i][j]+=dp[i-1][j];
				if(dp[i][j-1]!=-1)dp[i][j]+=dp[i][j-1];
			}
		}
	}
	cout<<dp[n+1][m+1];
	return 0;
} 

在地图上标记好马的位置与马能走到的另外八个位置,在状态转移的时候记得注意该点状态永远为0。最后输出终点的状态。

NC16619 传球游戏:

#include<bits/stdc++.h>
using namespace std;
int n,m;
long long dp[105][105];
int main(){
	cin>>n>>m;
	dp[0][1]=1;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			if(j==1){
				dp[i][j]=dp[i-1][n]+dp[i-1][j+1];
			}
			else if(j==n){
				dp[i][j]=dp[i-1][1]+dp[i-1][j-1];
			}
			else{
				dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1];
			}
		}
	}
	cout<<dp[m][1];
	return 0;
}

dp[i][j]表示在传球次数达到i次时球到达j手上的方法数,状态转移方程我们可以由球只能从左右两侧传来,所以知方程dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1],注意特判j=1和n的情况。

NC16810 [NOIP1999]拦截导弹:

#include <bits/stdc++.h>
using namespace std;
int a[1001],dp[1001];
int main()
{int p=0,flag=0;

   while(cin>>a[++p])
   {

   }
   p--;
   int ans=0;
   for(int i=1;i<=p;i++)
       { flag=0;
        for(int j=i-1;j>=1;j--)
           if (a[i]<=a[j]) flag=max(flag,dp[j]);
         if (flag==0) dp[i]=1;
         else dp[i]=flag+1;
         ans=max(ans,dp[i]);
         //cout<<dp[i]<<endl;
       }
       cout<<ans<<endl;
      memset(dp,0,sizeof(dp));
       ans=0;
   for(int i=1;i<=p;i++)
       { flag=0;
        for(int j=i-1;j>=1;j--)
           if (a[i]>a[j]) flag=max(flag,dp[j]);
         if (flag==0) dp[i]=1;
         else dp[i]=flag+1;
         ans=max(ans,dp[i]);
         //cout<<dp[i]<<endl;
       }
       cout<<ans<<endl;
    return 0;
}

Dilworth定理:最小链覆盖=最长反链长度,所以需要的系统就为这个序列的最长上升列长度,而一个系统最多能拦截的值就为反转的数列的最长上升子序列长度。求两个最长上升子序列即可。

NC16664 [NOIP2004]合唱队形:

#include<bits/stdc++.h>
using namespace std;
int a[1005];int dp1[1005],dp2[1005];
int main(){
	int n,ans=0;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	dp1[1]=1;
	for(int i=1;i<=n;i++){
		int m=0;
		for(int j=1;j<i;j++){
			if(a[i]>a[j]&&dp1[j]>m)m=dp1[j];
			//cout<<dp1[i]<<endl;
		}
		dp1[i]=m+1;
	}
	dp2[n]=1;
	for(int i=n;i;i--){
		int m=0;
		for(int j=n;j>i;j--){
			if(a[i]>a[j]&&dp2[j]>m)m=dp2[j];
		}
		dp2[i]=m+1;
	}
	for(int i=1;i<=n;i++){
		ans=max(ans,dp1[i]+dp2[i]-1);
	}
	//cout<<n<<" "<<ans<<endl;
	cout<<n-ans<<endl;
	return 0;
}

最长上升子序列的变式。先从左往右求一遍最长上升子序列(dp1),再从右往左求一遍(dp2)。
结果遍历一遍从左和从右的dp值和(dp1[i]+dp2[i]),找出和为最大的即为最大正常先递增再递减的子序列长度。

NC235954 滑雪:

#include<bits/stdc++.h>
using namespace std;
const int N = 310;
int n, m;
int g[N][N];
int f[N][N];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int dp(int x, int y){
    int &v = f[x][y];
    if (v != -1) return v;

    v = 1;
    for (int i = 0; i < 4; i ++ ){
        int a = x + dx[i], b = y + dy[i];
        if (a >= 1 && a <= n && b >= 1 && b <= m && g[x][y] > g[a][b])
            v = max(v, dp(a, b) + 1);
    }

    return v;
}

int main(){
    cin>>n>>m;
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            scanf("%d", &g[i][j]);
    memset(f, -1, sizeof f);
    int res = 0;
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            res = max(res, dp(i, j));
    printf("%d\n", res);

    return 0;
}

经典的记忆化搜索的题,我觉得比起dp更像搜索。从最高点开始向四周搜索,结束时一定是最长的路径在dp中,因为搜索结束了就表示最长的那条线已经走完了。

NC235948 最大子串和:

#include<bits/stdc++.h>
using namespace std;
long long a[1000005],dp[1000005];
int main(){
	long long n,ans=0;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		dp[i]=max(dp[i-1]+a[i],dp[i]);
		ans=max(ans,dp[i]);
	}
	cout<<ans;
	return 0;
}

从某一个数字来看,它的最大连续子串和是前面一个数字的最大连续子串和加上它本身,和他本身取较大的那一个。当位于第一个的时候自然就是他自身所以可以实现一个动态规划。故递推式:dp[i] = max(dp[i-1]+dp[i], dp[i])。

NC235624 牛可乐和最长公共子序列:

#include<bits/stdc++.h>
using namespace std;
int dp[5005][5005];
int main(){
	string s,t;
	while(cin>>s>>t){
        if(s[0]==t[0])dp[1][1]=1;
		int ans=0;
		//memset(dp,0,sizeof(dp));
		int n=s.size(),m=t.size();
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(s[i-1]==t[j-1])dp[i][j]=dp[i-1][j-1]+1;
				else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
				ans=max(dp[i][j],ans);
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

最长上升子序列的模板题。

后记:

  刷题的日子才过去两天怎么感觉我现在已经有点萎了,果然坚持下去是一件非常难的事啊。加油吧!

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

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

相关文章

郑州大学人工智能简答

第一章 1. 什么是人工智能&#xff1f; 人工智能又称机器智能&#xff0c;主要研究人工的方法和技术开发智能机器或智能系统&#xff0c;以模仿、延伸和扩展人的智能、生物智能、自然智能&#xff0c;实现机器的智能行为。 人工智能的定义分四类&#xff1a; &#xff08;1&am…

切线与切平面的可视化

切线与切平面的可视化 flyfish 切线的可视化 import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation, PillowWriter# 定义一个简单的一元函数&#xff0c;例如 f(x) x^2 def func(x):return x**2# 计算函数的导数 def deriva…

Docker搭建ELK

docker安装ElasticSearch 创建网络 #这里先创建一个网络&#xff1a;因为我们还需要部署kibana容器、logstash容器&#xff0c;需要让这些容器互联。 docker network create elk-net#查看网络 docker network ls下载ES镜像 #搜索镜像 docker search elasticsearch #下载镜像…

【活动】搜维尔科技携Xsens邀您出席世界人工智能大会

展会介绍 由外交部、国家发展改革委、教育部、科技部、工业和信息化部、国家网信办、中国科学院、中国科协和上海市政府共同主办的世界人工智能大会&#xff08;WAIC&#xff09;&#xff0c;将于7月4日-7日在上海举行。围绕“以共商促共享 以善治促善智”主题&#xff0c;打造…

【MySQL】数据库事务详解

文章目录 前言1. 事务的定义2. 事务的四个特性2.1 原子性2.2 一致性2.3 隔离性2.4 持久性 3. 事务的并发问题3.1 脏读3.2 不可重复读3.3 幻读3.4 更新丢失 4. 事务的隔离级别5. 事务的使用结语 前言 假设我们现在需要操作数据库进行转账&#xff0c;A 给 B 转账 100 块钱&…

【Linux】进程信号_3

文章目录 八、进程信号2. 信号的保存3. 信号的处理 未完待续 八、进程信号 2. 信号的保存 实际执行信号的处理动作称为信号递达(Delivery) 信号从产生到递达之间的状态,称为信号未决(Pending)。 进程可以选择阻塞 (Block )某个信号。 被阻塞的信号产生时将保持在未决状态,直到…

6.26作业

1.整理思维导图 2.统计家目录下.c文件的个数 ls ~/*.c | wc -l 3.终端输入一个.sh文件&#xff0c;判断文件是否由可执行权限&#xff0c;如果有可执行权限运行脚本&#xff0c;没有可执行权限添加可执行权限后&#xff0c;再运行脚本 #!/bin/bash read -p "请输入一个.…

Go语言学习:每日一练1

Go语言学习&#xff1a;每日一练1 目录 Go语言学习&#xff1a;每日一练1变量声明函数定义流程控制 ifrange遍历switch 变量声明 package main//定义变量 var a 1 const Message “hello,world”func main() {b : 2 //短变量声明var c 3c TestMethod(a, b, c)} //定义函数…

基于IM948(Low-cost IMU+蓝牙)模块的高精度PDR(Pedestrian Dead Reckoning)定位系统 — 可以提供模块和配套代码

一、背景与意义 行人PDR定位系统中的PDR&#xff08;Pedestrian Dead Reckoning&#xff0c;即行人航位推算&#xff09;背景意义在于其提供了一种在GPS信号不可用或不可靠的环境下&#xff0c;对行人进行精确定位和导航的解决方案。以下是关于PDR背景意义的详细描述&#xff1…

【课程总结】Day11(中):手势图像识别实战(Vgg16和ResNet)

前言 在上一章《【课程总结】Day11&#xff08;上&#xff09;&#xff1a;手势图像识别实战(LeNet模型)》课程中&#xff0c;我们通过使用LeNet模型实现了手势识别。在本章内容中&#xff0c;我们将搭建Vgg模型和ResNet模型&#xff0c;并应用到手势识别中。 Vgg模型 Vgg简…

egg代码生成器

今天给大家分享一下egg的代码生成器&#xff0c;这个其实原理很简单&#xff0c;说白了就是用到了nodejs的一个文件io的操作&#xff0c;通过一系列配置参数解析然后生成一个很长的字符串&#xff0c;写入到文件中&#xff0c;最后导出到我们指定的文件夹。 前提概要 为什么我…

网工内推 | 国企信息工程师,信息系统项目管理师优先,最高14薪

01 上海浦东软件园股份有限公司 &#x1f537;招聘岗位&#xff1a;信息化管理工程师 &#x1f537;岗位职责&#xff1a; 1. 根据公司战略、数字化总体架构规划和IT 技术趋势&#xff0c;制定信息化系统的规划与设计&#xff0c;并制定实施计划。 2. 统筹公司信息化系统管理…

【Linux详解】进程的状态 | 运行 阻塞 挂起 | 僵尸和孤儿状态

目录 操作系统中 运行状态 阻塞状态 进程状态转换 Linux系统中 查看进程状态 深度睡眠状态 T 暂停状态 Z 僵尸状态 孤儿状态 文章手稿 xmind: 引言 介绍系统中的进程状态及其管理方式。将通过结合操作系统原理和实际代码示例&#xff0c;详细说明进程的各种状态、转换…

Java Stream API揭秘:掌握List流操作,打造高效数据处理流程

序言 Java Stream API是Java 8中引入的一个非常重要的功能组成部分&#xff0c;它提供了一种声明式的处理数据集合的方法。它主要特点是基于函数式编程的理念&#xff0c;允许我们以更加简洁、高效的方式进行集合的处理、转换和过滤。通过Stream API&#xff0c;我们可以灵活地…

暗黑4PTR怎么参与测试 暗黑4第五赛季怎么参加PTR测试教程

暗黑破坏神4作为暗黑破坏神系列的最新作品&#xff0c;自从2023年上线就受到了一众好评。游戏是动作冒险类角色扮演游戏&#xff0c;游戏的背景设定在一个腐化的圣休瑞亚大陆上&#xff0c;玩家们可以五种职业中选择自己喜爱的游戏进行游戏。 暗黑破坏神4第五赛季现在已经开启P…

机器学习数学原理专题——线性分类模型:损失函数推导新视角——交叉熵

目录 二、从回归到线性分类模型&#xff1a;分类 3.分类模型损失函数推导——极大似然估计法 &#xff08;1&#xff09;二分类损失函数——极大似然估计 &#xff08;2&#xff09;多分类损失函数——极大似然估计 4.模型损失函数推导新视角——交叉熵 &#xff08;1&#x…

SpringCloud_GateWay服务网关

网关作用 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由和负载均衡&#xff1a;一切请求都必须先经过gateway&#xff0c;但网关不处理业务&#xff0c;而是根据某种规则&#xff0c;把请求转发到某个微服务&a…

Python数据分析-糖尿病数据集数据分析

一、研究背景介绍 糖尿病是美国最普遍的慢性病之一&#xff0c;每年影响数百万美国人&#xff0c;并对经济造成重大的经济负担。糖尿病是一种严重的慢性疾病&#xff0c;其中个体失去有效调节血液中葡萄糖水平的能力&#xff0c;并可能导致生活质量和预期寿命下降。。。。糖尿…

如何借助物联网实现土壤监测与保护

如何借助物联网实现土壤监测与保护 高标准农田信息化是指利用现代信息技术&#xff0c;如物联网、大数据、云计算等&#xff0c;对农田进行数字化、智能化的管理&#xff0c;以提高农田的生产效率和可持续发展能力。其中&#xff0c;土壤监测与保护是农田信息化的重要内容之一…

解决SD卡被写保护问题

存储卡在使用过程中&#xff0c;有时会遇到写保护问题&#xff0c;导致无法写入或删除数据。这可能会对用户的正常使用造成困扰。MK米客方德将为您介绍几种常见的解决方法&#xff0c;帮助用户解除存储卡的写保护。 一、检查物理写保护开关 许多存储卡&#xff0c;如SD卡&…