晴问算法 动态规划(简单)

news2024/11/13 14:53:01

动态规划的递归写法和递推写法

斐波那契数列II

题目描述

给定正整数�,求斐波那契数列的第�项�(�)。

令�(�)表示斐波那契数列的第�项,它的定义是:

当�=1时,�(�)=1;

当�=2时,�(�)=1;

当�>2时,�(�)=�(�−1)+�(�−2)。

输入描述

一个正整数�​(1≤�≤104​)。

输出描述

斐波那契数列的第�项�(�)。

由于结果可能很大,因此将结果对10007取模后输出。

#include <cstdio>
int fib[10001]={0};

int main() {
    int n;
    scanf("%d", &n);
    fib[1] = fib[2] = 1;
    for (int i = 3; i <= n; i++) {
        fib[i] = (fib[i - 1] + fib[i - 2])%10007;
    }
    printf("%d", fib[n]);
    return 0;
}

数塔II

题目描述

7(1).png

数塔就是由一堆数字组成的塔状结构,其中第一行1个数,第二行2个数,第三行3个数,依此类推。每个数都与下一层的左下与右下两个数相连接。这样从塔顶到塔底就可以有很多条路径可以走,现在需要求路径上的数字之和的最大值。

例如在上图中,5->8->12->105->3->16->11这两条路径上的数字之和都是35,是所有路径中的最大值。

输入描述

第一行一个正整数�​(1≤�≤100​),表示数塔的层数。

接下来�​行为数塔从上到下的每一层,其中第�​层有�​个正整数,每个数都不超过1000

输出描述

从塔顶到塔底的所有路径中路径上数字之和的最大值。

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

上楼II

题目描述

我打算走楼梯上楼,共有�级台阶。

我身轻如燕,所以每次都可以选择上一级台阶或者两级台阶。

问有多少种上楼的方式。

例如当�=3时,共有三种方式上楼:

  1. 一级 => 一级 => 一级;
  2. 一级 => 二级;
  3. 二级 => 一级。

输入描述

一个正整数�​(1≤�≤104​),表示台阶级数。

输出描述

一个整数,表示上楼的方案数。

由于结果可能很大,因此将结果对10007取模后输出。

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

最大连续子序列和

最大连续子序列和

题目描述

现有一个整数序列�1,�2,...,��​​​,求连续子序列��+...+��​​​的最大值。

输入描述

第一行一个正整数�​​(1≤�≤104​​),表示序列长度;

第二行为用空格隔开的�​个整数��​(−105≤��≤105​​),表示序列元素。

输出描述

输出一个整数,表示最大连续子序列和。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    int a,b;
    int max1=-2222222;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a;
        if(i==1) b=a;
        else b=max(a,a+b);
        max1=max(max1,b);

    }
    cout<<max1;
    return 0;

}

最长不下降子序列(LIS)

最长上升子序列

题目描述

现有一个整数序列�1,�2,...,��​​​​​​,求最长的子序列(可以不连续),使得这个子序列中的元素是非递减的。输出该最大长度。

输入描述

第一行一个正整数�​​​​(1≤�≤100​​​​),表示序列长度;

第二行为用空格隔开的�​个整数��​(−105≤��≤105​​),表示序列元素。

输出描述

输出一个整数,表示最大长度。

#include<iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int a[1001]={0};
	int dp[1001]={0};
	int maxn=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		dp[i]=1;
		for(int j=1;j<i;j++){
			if(a[j]<=a[i]){
				dp[i]=max(dp[i],dp[j]+1);
				
			}

		}
		if(dp[i]>maxn) maxn=dp[i];
	}
	cout<<maxn;
	return 0;
} 

最长公共子序列(LCS)

最长公共子序列

题目描述

现有两个字符串�1​​​​与�2​,求�1​​​​与�2​​​​的最长公共子序列的长度(子序列可以不连续)。

输入描述

第一行为字符串�1​​,仅由小写字母组成,长度不超过100

第一行为字符串�2​​​,仅由小写字母组成,长度不超过100

输出描述

输出一个整数,表示最长公共子序列的长度。

#include<bits/stdc++.h>
using namespace std;
int main(){
    string a,b;
    cin>>a>>b;
    int dp[102][102]={0};
    for(int i=1;i<=a.length();i++){
        for (int j = 1; j <= b.length(); j++){
            if(a[i-1]==b[j-1]){
                dp[i][j]=dp[i-1][j-1]+1;
            }else{
                dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
            }
        }
    }
    cout<<dp[a.length()][b.length()];
    return 0;
}

最长回文子串

最长回文子串

题目描述

现有一个字符串�,求�的最长回文子串的长度。

输入描述

一个字符串�​​​​,仅由小写字母组成,长度不超过100

输出描述

输出一个整数,表示最长回文子串的长度。

//中点扩散算法
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int dp[N][N];
int main()
{
    string str;
    getline(cin,str);
    int res=0;
    for(int i=0;i<str.length();i++)
    {
        int l=i-1,r=i+1;//判断奇数长度回文串
        while(l>=0&&r<str.length()&&str[l]==str[r]) l--,r++;
        res=max(res,r-l-1);
        l=i,r=i+1;//判断偶数长度回文串
        while(l>=0&&r<str.length()&&str[l]==str[r]) l--,r++;
        res=max(res,r-l-1);
    }
    cout<<res<<endl;
    return 0;
}

背包问题

01背包问题

题目描述

有�件物品,每件物品的重量为��,价值为��。现在需要选出若干件物品放入一个容量为�的背包中(每件物品至多选一次),使得在选入背包的物品重量之和不超过容量�的前提下,让背包中物品的价值之和最大,求最大价值。

输入描述

第一行两个整数�​、�​(1≤�≤100,1≤�≤103​),分别表示物品数量、背包容量;

第二行为用空格隔开的�​个整数��​(1≤��≤10​),表示物品重量;

第三行为用空格隔开的�​个整数��​(1≤��≤10​),表示物品价值。

输出描述

输出一个整数,表示最大价值。

#include<bits/stdc++.h>
using namespace std ;
int ti[1005] , pri[1005] ;
int f[1005][1005] ;
int main()
{
	int t , m ;
	cin >> m>> t ;
    for(int i = 1 ; i <= m ; ++i){
        cin >> ti[i];
    }
    for(int i = 1 ; i <= m ; ++i){
        cin >> pri[i];
    }
	for(int i = 1 ; i <= m ; ++i)
	{
        for(int j = 1 ; j <= t ; ++j)
		{
			f[i][j] = f[i - 1][j] ;
            if(j >= ti[i]) 
				f[i][j] = max(f[i][j], f[i - 1][j - ti[i]] + pri[i]) ;
        }
    }
    cout << f[m][t] ;
	return 0 ;
}

完全背包问题

题目描述

有�​种物品,每种物品的重量为��​,价值为��​。现在需要选出若干件物品放入一个容量为�​的背包中(每种物品可以选任意次),使得在选入背包的物品重量之和不超过容量�​​的前提下,让背包中物品的价值之和最大,求最大价值。

输入描述

第一行两个整数�​、�​(1≤�≤100,1≤�≤103​),分别表示物品数量、背包容量;

第二行为用空格隔开的�​个整数��​(1≤��≤100​),表示物品重量;

第三行为用空格隔开的�​个整数��​(1≤��≤100​),表示物品价值。

输出描述

输出一个整数,表示最大价值。

#include<bits/stdc++.h>
using namespace std;
int a[1002]={0},b[1002]={0};
int f[1002]={0};
int main(){
    int n,v;
    cin>>n>>v;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    for(int i=1;i<=n;i++){
        for(int j=a[i];j<=v;j++){
			f[j] = max(f[j], f[j - a[i]] +b[i]);
        }
    }
    cout << f[v];
    return 0;
}

01背包问题的方案数

题目描述

有�​件物品,每件物品的重量为��​。现在需要选出若干件物品放入一个容量为�​的背包中(每件物品至多选一次),使得选入背包的物品重量之和恰好等于容量�​​​​。求满足条件的方案数。

输入描述

第一行两个整数�​、�​(1≤�≤100,1≤�≤103​),分别表示物品数量、背包容量;

第二行为用空格隔开的�​个整数��​(1≤��≤10​),表示物品重量。

输出描述

输出一个整数,表示方案数。由于结果可能很大,因此将结果对10007取模后输出。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int N,M;
	cin>>N>>M;
	int a[1005],dp[10050];
	for(int i=1;i<=N;i++){
		cin>>a[i];
	}
	dp[0]=1;
	for(int i=1;i<=N;i++){
		for(int j=M;j>=a[i];j--){
			dp[j]=(dp[j]+dp[j-a[i]])%10007;
		}
	}
	cout<<dp[M];
	return 0;
}

总结

最小消耗能量

题目描述

现有�个从左至右摆放着的高台(编号为从1n),每个高台有各自的高度ℎ�。假设闯关者当前处于第�个高台,那么可以选择跳到第�+1或第�+2个高台(闯关者能够跳任意高度)。如果从第�个高台跳到第�个高台,那么将会消耗闯关者|ℎ�−ℎ�|点能量。问从第1个高台出发、到达第�个高台的过程中需要消耗的最小能量。

输入描述

第一行一个整数�(1≤�≤104),表示高台个数。

第二行为用空格隔开的�个整数ℎ�(1≤ℎ�≤100),表示各高台的高度。

输出描述

一个整数,表示需要消耗的最小能量。

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

}

矩阵最大权值

题目描述

现有一个�∗�​大小的矩阵,矩阵中的每个元素表示该位置的权值。现需要从矩阵左上角出发到达右下角,每次移动只能向右或者向下移动一格。求最后到达右下角时路径上所有位置的权值之和的最大值。

输入描述

第一行两个整数�​​​​、�​​​​(1≤�≤100,1≤�≤100​​​​),分别表示矩阵的行数和列数;

接下来�​​​行,每行�​​​个整数(−100≤​​整数≤100​​​),表示矩阵每个位置的权值。

输出描述

一个整数,表示权值之和的最大值。

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

 最小涂色成本

题目描述

现有�​​​张不同大小的白纸排成一排,每张白纸可以涂成红、黄、蓝三种颜色之一,但不能有连续两张白纸涂成相同的颜色。假设给第�​​​张白纸涂红色需要消耗的成本为��​​​,涂黄色需要消耗的成本为��​​,涂蓝色需要消耗的成本为��​​,求把�​​​​张白纸全部涂色需要的最小成本。

输入描述

第一行一个整数�​​​​​​​​​​​(1≤�≤104​​​​​​​),表示白纸张数;

接下来�行,每行三个整数,表示第�张白纸分别涂红、黄、蓝三种颜色需要消耗的成本��、��、��(1≤��≤100,1≤��≤100,1≤��≤100​)。

输出描述

一个整数,表示最小成本。

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

}

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

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

相关文章

【MD】激光驱动原子动力学的全尺寸从头算模拟

Zeng Q, Chen B, Zhang S, et al. Full-scale ab initio simulations of laser-driven atomistic dynamics[J]. npj Computational Materials, 2023, 9(1): 213.核心研究内容&#xff1a; 本文研究了激光驱动的原子动力学的全尺度从头算模拟。研究的重点是探讨在极端条件下材料…

C语言结构体之位段

位段&#xff08;节约内存&#xff09;&#xff0c;和王者段位联想记忆 位段是为了节约内存的。刚好和结构体相反。 那么什么是位段呢&#xff1f;我们现引入情景&#xff1a;我么如果要记录一个人是男是女&#xff0c;用数字0 1表示。我们发现只要一个bit内存就可以完成我们想…

讯优随身WiFi可靠吗?讯优和格行随身WiFi哪个好?随身wifi推荐测评!随身WiFi哪个牌子比较好用?随身WiFi怎么选?随身WiFi推荐第一名!

随身WiFi挑花眼&#xff1f;不知道哪款好用&#xff1f;今天&#xff0c;我将为大家带来迅优与格行两大随身WiFi品牌的真实测评。 价格方面&#xff1a;迅优随身WiFi以价格优惠为卖点&#xff0c;吸引了众多消费者的目光。对于预算有限的用户来说&#xff0c;迅优确实提供了一个…

刷题记录:最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl"示例 2&#xff1a; 输…

治疗植物神经功能紊乱的关键竟是它!

植物神经紊乱&#xff0c;是指交感神经系统和副交感神经系统之间的平衡失调&#xff0c;导致心率不规律、胃肠问题、焦虑、失眠等一系列症状。长期植物神经紊乱可能导致更严重的心血管疾病、消化系统问题以及心理健康隐患。它可能源于饮食结构失衡、物理环境压力过大、心理压力…

Xinstall:用智能数据传递,打造高效的App推广体系

随着移动互联网的快速发展&#xff0c;App已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;对于开发者来说&#xff0c;如何有效地推广App并衡量推广效果却是一个巨大的挑战。这时&#xff0c;Xinstall作为一站式App全渠道统计服务商&#xff0c;提供了强有力的解决方…

模板(一)

文章目录 模板&#xff08;一&#xff09;1.泛型编程2.函数模板2.1函数模板概念2.2函数模板格式2.3函数模板的原理2.4函数模板的实例化2.4.1隐式实例化2.4.2显式实例化 2.5模板参数的匹配原则 3.类模板3.1类模板的定义格式3.2类模板的实例化 模板&#xff08;一&#xff09; 1…

25.7 MySQL 数据库和表的基本操作

1. 基础知识 1.1 一条数据的存储过程 存储数据确实是处理数据的基石, 只有确保数据被准确无误且有条理地存储, 我们才能对其进行深入的处理和细致的分析. 否则, 这些数据就像是一团毫无章法的乱麻, 让我们难以捉摸其内在的逻辑和价值.那么, 如何才能够将用户那些与经营紧密相关…

人工智能时代如何高效完成营销内容计划

智能对话升级&#xff01;【Kompas AI】AI对话助手&#xff0c;让沟通更高效 在人工智能时代&#xff0c;要高效完成营销计划&#xff0c;我们可以利用人工智能的多种能力来增强营销策略的精准度和执行效率。借助人工智能的力量&#xff0c;企业不仅可以提高营销计划的执行效率…

Rust高级爬虫:如何利用Rust抓取精美图片

引言 在当今信息爆炸的时代&#xff0c;互联网上的图片资源丰富多彩&#xff0c;而利用爬虫技术获取这些图片已成为许多开发者的关注焦点。本文将介绍如何利用Rust语言进行高级爬虫编程&#xff0c;从而掌握抓取精美图片的关键技术要点。 Rust爬虫框架介绍 Rust语言生态中有…

一文说清:AI大模型在制造业中的应用类型

在过去的几年里&#xff0c;全球制造业的竞争格局正在发生重构&#xff0c;数字化和智能化成为推动变革的关键力量。AI 大模型作为一种通用人工智能技术&#xff0c;其革命性特征体现在能够生成代码、构建人机交互新模式&#xff0c;并与产品研发、工艺设计、生产作业、产品运营…

2024软考

报考链接&#xff1a; 中国计算机技术职业资格网 (ruankao.org.cn) 报名有效时间&#xff1a; 天津2024-03-24 09:00 ~ 2024-04-02 17:00 河北2024-03-20 09:30 ~ 2024-03-26 17:00 山西2024-03-18 14:30 ~ 2024-04-02 11:30 宁波2024-03-20 10:00 ~ 2024-03-26 16:00 辽宁…

C语言调用云端 Python接口

利用C语言调用阿里云Python接口&#xff0c;来实现垃圾的智能识别 文章目录 利用C语言调用阿里云Python接口&#xff0c;来实现垃圾的智能识别1、如何开启阿里云服务2、实验程序介绍2.1 py程序改造2.2 c语言调用py2.3 测试代码 3、实验结果 1、如何开启阿里云服务 大家可以自行…

RHCE作业:搭建web网站

综合练习&#xff1a; 请给openlab搭建web网站 网站需求&#xff1a; 1.域名访问网站 基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!! 2.创建界面 给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料 和缴费网站&#xff0c;基于www.openlab.com…

【精简】Spring笔记

文章目录 跳转链接&#xff08;学习路线&#xff09;及前言&#xff08;更新中&#xff09; 快速入门配置文件详解依赖注入(bean实例化)自动装配集合注入使用spring加载properties文件容器注解开发bean管理注解开发依赖注入第三方bean整合mybatis整合junit AOP入门案例切入点表…

【git分支管理策略】如何高效的管理好代码版本

目录 1.分支管理策略 2.我用的分支管理策略 3.一些常见问题 1.分支管理策略 分支管理策略就是一些经过实践后总结出来的可靠的分支管理的办法&#xff0c;让分支之间能科学合理、高效的进行协作&#xff0c;帮助我们在整个开发流程中合理的管理好代码版本。 目前有两套Git…

奇偶校验|ECC内存|海明码

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;本篇文章给大家介绍数据出错和有什么方法能减少出错。 单比特翻转 由于硬件故障或其他原因&#xff0c;内存或其他存储设备中的单个比特位发生随机变化的现象。 例如&#xff0c;原本存储为1的位可能变为0&#xff0c;或…

放弃 Rust 选择 Zig,Xata 团队推出 pgzx —— 计划使用 Zig 开发基于 PG 的分布式数据库

Summary Xata 公司在基于 PostgresSQL 开发自己的分布式数据库&#xff0c;出于 Zig 和 C 语言以及 PostgreSQL 的 API 有更好的互操作性的考虑&#xff0c;他们选择了 Zig 而非当红炸子鸡语言 Rust。他们的博客文章中对 pgzx 进行了介绍。让我们来看下他们对 Zig 和 Rust 语言…

创建多节点 k8s 集群

主机IP系统master192.168.2.15ubuntu20.04 x64 2C 4GWorker1192.168.2.16ubuntu20.04 x64 2C 4GWorker1192.168.2.18ubuntu20.04 x64 2C 4G 使用 iterm2 连接四台服务器 command shift i 同时操作 初始化配置 关闭防火墙 systemctl stop firewalld systemctl disable firewa…

Qt篇——Qt无法翻译tr()里面的字符串

最近遇到使用Qt语言家翻译功能时&#xff0c;ui界面中的中文都能够翻译成英文&#xff0c;但是tr("测试")这种动态设置给控件的中文&#xff0c;无法翻译&#xff08;lang_English.ts文件中的翻译已经正确添加了tr()字符串的翻译&#xff09;。 上网搜了很多资料&am…