PTA-2023年软件设计综合实践_9(动态规划法)

news2025/1/25 5:06:42

7-1 数塔

数塔如图所示,若每一步只能走到相邻的结点(图中有数字的方格),则从最顶层走到最底层所经过的所有结点的数字之和最大是多少?测试数据保证结果不大于231−1。

数塔1.png

 C++

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

int main(){
    int n;
    cin>>n;
    while(n--){
        int a[101][101]={0};
        int dp[101][101]={0};
        int high;//最高层号
        cin>>high;
        for(int i=1;i<=high;i++){
            for(int j=1;j<=i;j++){
                cin>>a[i][j];
                if(i==high){
                    dp[i][j]=a[i][j];//递推边界
                }
            }
        }
        for(int i=high-1;i>=1;i--){
            for(int j=1;j<=i;j++){
                dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];
            }
        }
        cout<<dp[1][1]<<endl;
    }  
}

7-2 最大子列和问题

给定K个整数组成的序列{ N1​, N2​, ..., NK​ },“连续子列”被定义为{ Ni​, Ni+1​, ..., Nj​ },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:

  • 数据1:与样例等价,测试基本正确性;
  • 数据2:102个随机整数;
  • 数据3:103个随机整数;
  • 数据4:104个随机整数;
  • 数据5:105个随机整数;

输入格式:

#include<iostream>
using namespace std;
 
int main() {
	int K, sum = 0;
	int number[100000];
 
	cin >> K;
 
	for (int i = 0; i < K; i++) {
		cin >> number[i];
	}
 
	for (int i = 0; i < K; i++) {
		int temp = 0;
		for (int j = i; j < K; j++) {
			temp += number[j];
 
			if (temp > sum) {
				sum = temp;
			}
		}
	}
 
	cout << sum;
 
	return 0;
}

7-3 最长公共子序列

给定两个长度分别为 N 和 M 的字符串 A 和 B,求既是 A 的子序列又是 B 的子序列的字符串长度最长是多少。

#include <iostream>
using namespace std;
const int N = 1010;
int n, m;
char a[N], b[N];
int f[N][N];
int main() {
    cin >> n >> m >> a + 1 >> b + 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i] == b[j]) {
                //找到一个公共字符,故长度加1
                f[i][j] = f[i - 1][j - 1] + 1;
            } else {
                //没找到则找到临近最大的一个长度,表示最大长度还没有变化
                //【为什么只需要找临近呢?因为dp数组中抽象地保存之前的状态,所以已经包含前面比较短的情况,再者,因为保存之前的状态,现在遍历到的这个位置,临近的元素就是之前状态的长度,因为我现在需要长度不变,所以在临近找一个最大的即可。】
                f[i][j] = max(f[i - 1][j], f[i][j - 1]);
            }
        }
    }
  cout << f[n][m] << '\n';
  return 0;
}

7-4 jmu-ds-最长公共子串

给出2个字符串,输出2字符串的最长公共子串。

输入格式:

输入2个字符串,不可包含空格。

输出格式:

输出2个字符串的最长公共子串。若没有公共子串,则输出“NULL”

python

a = input()
b = input()
def maxSubstring(a,b):
    if a==None or b==None:#空值返回
        return None
    #接下来获取两者较长和较短的字符串
    if len(a)>len(b):
        M=a
        m=b
    else:
        M=b
        m=a
    #遍历遍历较短的字符串,并依次减少短字符串的字符数量,
    #判断长字符是否包含该子串
    i=0
    while i<len(m):
        begin=0
        end=len(m)-i
        #先扣住end部分的字符,然后一个循环看begin从0~end是否有符合的最大串
        while end<=len(m):
            current=m[begin:end]
            if current in M:
                return current
            begin+=1
            end+=1
        i+=1
    return 'NULL'
print(maxSubstring(a,b))

7-5 最长有序子序列

对于给定一个数字序列 (a1​,a2​,…,an​) ,如果满足a1​<a2​<…<an​,则称该序列是有序的。若在序列(a1​,a2​,…,an​) 中删除若干元素得到的子序列是有序的,则称该子序列为一个有序子序列。有序子序列中长度最大的即为最长有序子序列。

例如,(1,3,5)、(3,5,8)、(1,3,5,9)等都是序列 (1,7,3,5,9,4,8) 的有序子序列;而(1,3,5,9)、(1,3,5,8)、(1,3,4,8)都是序列 (1,7,3,5,9,4,8)的一个最长有序子序列,长度为4。

请编写程序,求出给定数字序列中的最长有序子序列的长度。

python

def longest_ordered_subsequence(nums):
    # 获取数字序列的长度
    n = len(nums)
    
    # 创建一个数组来保存以每个元素结尾的最长有序子序列的长度
    dp = [1] * n
    
    # 计算最长有序子序列的长度
    for i in range(1, n):
        for j in range(i):
            if nums[i] > nums[j]:
                dp[i] = max(dp[i], dp[j] + 1)
    
    # 返回最长有序子序列的最大长度
    return max(dp)

# 读取输入数据的数量
T = int(input())

for _ in range(T):
    # 读取数字序列的长度和元素
    n = int(input())
    sequence = list(map(int, input().split()))
    
    # 计算并输出最长有序子序列的长度
    result = longest_ordered_subsequence(sequence)
    print(result)
    
    # 输出空行(除了最后一组测试数据)
    if _ != T - 1:
        print()

7-6 跳房子

跳房子是小朋友玩的游戏。地面上画出一连串格子,每个格子里有一个整数,小朋友从外面跳入格子,并继续往前跳,直到跳出所有格子。每次跳跃的规则是,可以跳入下一格或下下格或下下下格。怎么跳能让落脚格子里的数的累加和最小。

python3

n = int(input())  # 读入格子数  
nums = list(map(int, input().split()))  # 读入每个格子里的数
nums=nums+[0]

dp = [100000] * (n + 2)  # 初始化dp数组
dp[0] = 0   
dp[1] = nums[0]
  
for i in range(2, n + 2 ):  
    dp[i] = min(dp[i - 1] + nums[i-1], dp[i - 2] + nums[i-1], dp[i - 3] + nums[i-1])  # 计算当前格子的最小累加和  
  
print(dp[n+1])  # 输出结果

7-7 寻宝路线

在一个m行n列方格矩阵中,每一个方格内摆放着价值不等的宝贝(价值可正可负),让小明感到好奇的是,从左上角到达右下角的所有可能路线中,能捡到宝贝的价值总和最大是多少?而且这种达到最大值的路线
又有多少条?【注意:只能从一个格子向下或向右走到相邻格子,并且走到的格子宝贝一定会被捡起。】

c++

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int m, n;
    cin >> m >> n;

    vector<vector<int>> grid(m, vector<int>(n, 0));

    // 读取宝贝价值矩阵
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> grid[i][j];
        }
    }

    // 创建动态规划所需的二维数组
    vector<vector<int>> dp(m, vector<int>(n, 0));
    vector<vector<int>> ways(m, vector<int>(n, 0));

    dp[0][0] = grid[0][0];
    ways[0][0] = 1;

    // 初始化第一列和第一行
    for (int i = 1; i < m; ++i) {
        dp[i][0] = dp[i - 1][0] + grid[i][0];
        ways[i][0] = 1;
    }

    for (int j = 1; j < n; ++j) {
        dp[0][j] = dp[0][j - 1] + grid[0][j];
        ways[0][j] = 1;
    }

    // 计算其余位置的最大值和路径数量
    for (int i = 1; i < m; ++i) {
        for (int j = 1; j < n; ++j) {
            if (dp[i - 1][j] > dp[i][j - 1]) {
                dp[i][j] = dp[i - 1][j] + grid[i][j];
                ways[i][j] = ways[i - 1][j];
            } else if (dp[i - 1][j] < dp[i][j - 1]) {
                dp[i][j] = dp[i][j - 1] + grid[i][j];
                ways[i][j] = ways[i][j - 1];
            } else {
                dp[i][j] = dp[i - 1][j] + grid[i][j];
                ways[i][j] = ways[i - 1][j] + ways[i][j - 1];
            }
        }
    }

    int max_value = dp[m - 1][n - 1];
    int max_ways = ways[m - 1][n - 1];

    cout << max_value << " " << max_ways << endl;

    return 0;
}

7-8 硬币找零

用 n 种不同币值的硬币凑出 m 元,最少需要多少硬币。

输入格式:

第一行输入需要凑的钱数 m 和硬币的种类 n (0<m<100,0<n<10),第二行输入 n 种硬币的具体币值,假设硬币供应量无限多。

输出格式:

输出最少需要的硬币个数

输入样例:

在这里给出一组输入。例如:

PYTHON3

def min_coins(coins, m):
    dp = [float('inf')] * (m + 1)
    dp[0] = 0

    for i in range(1, m + 1):
        for coin in coins:
            if i >= coin:
                dp[i] = min(dp[i], dp[i - coin] + 1)

    return dp[m] if dp[m] != float('inf') else -1

if __name__ == "__main__":
    m, n = map(int, input().split())
    coins = list(map(int, input().split()))

    result = min_coins(coins, m)
    print(result)

7-9 至多删三个字符

给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串?

C++

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int dp[N][4];
 
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	string s, stemp;
	cin >> stemp;
	s.assign("0");
	s.append(stemp);
	dp[0][0] = 1;
	for (int i = 1; i < s.size(); ++i)
	{
		for (int j = 0; j <= 3; ++j)
		{
			dp[i][j] = dp[i - 1][j];
			if (j)
				dp[i][j] = dp[i][j] + dp[i - 1][j - 1];
			for (int k = i - 1; k >= 1 && i - k <= j; --k)
			{
				if (s[k] == s[i])
				{
					dp[i][j] = dp[i][j] - dp[k - 1][j - (i - k)];
					break;
				}
			}
		}
	}
	int ans = 0;
	for (int i = 0; i <= 3; ++i)
	{
		ans = ans + dp[s.size() - 1][i];
	}
	cout << ans << endl;
	return 0;
}

7-10 拼题A打卡奖励

拼题 A 的教超搞打卡活动,指定了 N 张打卡卷,第 i 张打卡卷需要 mi​ 分钟做完,完成后可获得 ci​ 枚奖励的金币。活动规定每张打卡卷最多只能做一次,并且不允许提前交卷。活动总时长为 M 分钟。请你算出最多可以赢得多少枚金币?

输入格式:

输入首先在第一行中给出两个正整数 N(≤103) 和 M(≤365×24×60),分别对应打卡卷的数量和以“分钟”为单位的活动总时长(不超过一年)。随后一行给出 N 张打卡卷要花费的时间 mi​(≤600),最后一行给出 N 张打卡卷对应的奖励金币数量 ci​(≤30)。上述均为正整数,一行内的数字以空格分隔。

C++

#include<bits/stdc++.h>
using namespace std;
const int N=1004;
const int INF=0x3f3f3f3f;
int n,m;
int w[N],v[N];
//int f[N][10000];
int dp[N][30005];//前i个物品中得到价值为j时候的最小花费 //ans为dp[n][j]<m时最大的j 
int mv=0;

int main()
{
//	cout<<365*60*24;
	cin>>n>>m;
	for(int i=1;i<=n;++i)cin>>w[i];
	for(int i=1;i<=n;++i){
		cin>>v[i];
		mv+=v[i];
	}

// 01背包写法,空间不够,而且也会超时,因为“花费”这一维度规模比较大,而递推时需要一一枚举
//		for(int i=1;i<=n;++i)
//		for(int j=0;j<=m;++j)
//		{
//			if(j>=w[i])
//			f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
//			else f[i][j]=f[i-1][j];
//		}
		

//下面是另一种思路,第二维换成价值
		//初始化 
		for(int i=0;i<=n;++i)
		{
			for(int j=0;j<=mv;++j){
				
				dp[i][j]=INF; 
			}
		}
		dp[0][0]=0;
		//递归过程:分为取第i个和不取第i个
		for(int i=1;i<=n;++i)
		{
			for(int j=0;j<=mv;++j){
				if(j>=v[i])//注意边界
				dp[i][j]=min(dp[i-1][j-v[i]]+w[i],dp[i-1][j]);
				else 
				dp[i][j]=dp[i-1][j];
			}
		}
		//可以改进递推过程:由于递归方程中两个来源都是上一个i的,去掉第一个维度,节省空间,注意这时候j要从大到小迭代,才能保证递推过程中的dp[j-v[i]]是来源于i-1而不是i
// 		for(int i=1;i<=n;++i)
// 		{
// 			for(int j=mv;j>=0;--j)
// 			{
// 				if(j>v[i])
// 				dp[j]=min(dp[j-v[i]]+w[i],dp[j]);
// 				else 
// 				dp[j]=dp[j];
// 		}
		//取答案:最小花费在给定的m内的最大价值
		for(int j=mv;j>=0;j--)
		{
			if(dp[n][j]<=m){
				cout<<j;
				break;
			}
		}

//	cout<<f[n][m];
	return 0;
}

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

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

相关文章

15个超级实用的Python操作,肯定有你意想不到的!

文章目录 1&#xff09;映射代理&#xff08;不可变字典&#xff09;2&#xff09;dict 对于类和对象是不同的3) any() 和 all()4) divmod()5) 使用格式化字符串轻松检查变量6) 我们可以将浮点数转换为比率7) 用globals()和locals()显示现有的全局/本地变量8) import() 函数9) …

Flink-时间流与水印

时间流与水印 一、背景二、时间语义1.事件时间&#xff08;event time&#xff09;2.读取时间&#xff08;ingestion time&#xff09;3.处理时间&#xff08;processing time&#xff09; 三、水印-Watermarks1.延迟和正确性2.延迟事件3.顺序流4.无序流5.并行流 四、Windows1.…

【Openstack Train安装】八、placement安装

Placement 肩负着这样的历史使命&#xff0c;最早在 Newton 版本被引入到 openstack/nova repo&#xff0c;以 API 的形式进行孵化&#xff0c;所以也经常被称呼为 Placement API。它参与到 nova-scheduler 选择目标主机的调度流程中&#xff0c;负责跟踪记录 Resource Provide…

Windows下命令行启动与关闭WebLogic的相关服务

WebLogic 的服务器类型 WebLogic提供了三种类型的服务器&#xff1a; 管理服务器节点服务器托管服务器 示例和关系如下图&#xff1a; 对应三类服务器&#xff0c; 就有三种启动和关闭的方式。本篇介绍使用命令行脚本的方式启动和关闭这三种类型的服务器。 关于WebLogic 的…

洗地机哪个牌子好用?希亦、添可、石头洗地机品牌实测推荐!

现代家居生活中&#xff0c;普通的扫把拖把已经快要脱离了普通百姓家&#xff0c;人们纷纷使用智能扫地机洗地机等。 但是现在市场上洗地机的品牌参差不齐&#xff0c;很多不懂行的人不知道该选什么&#xff0c;那么什么洗地机的品牌质量好且耐用呢&#xff1f;下面笔者为大家…

Azure Machine Learning - 创建Azure AI搜索索引

目录 一、先决条件检查空间 二、创建和加载索引启动向导连接到 数据源跳过认知技能配置配置索引配置索引器 三、监视索引器进度四、检查搜索索引结果五、添加或更改字段六、使用搜索浏览器查询七、运行更多示例查询八、清理资源 在本文中&#xff0c;你将使用导入数据向导和由虚…

解决msvcr71.dll丢失5个方法,修复程序运行缺失dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcr71.dll丢失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了很大的困扰。那么&#xff0c;究竟是什么原因导致了msvcr71.dll文件的丢失呢&#xff1f;本文…

T-Rex:检测一切 | 基于视觉提示的开集检测器,检测并计数

图1. 我们引入了一个交互式对象计数模型T-Rex。给定参考图像上指定的框或点&#xff0c;T-Rex 可以检测目标图像上的所有与指定对象表现出相似模式的实例&#xff0c;然后将其相加得到计数结果。我们先通过T-Rex生成检测到框提示&#xff0c;再使用SAM得到mask&#xff0c;以获…

Android端极致画质体验之HDR播放

高动态范围HDR视频通过扩大亮度分量的动态范围(从100cd/m2到1000cd/m2)&#xff0c;以及采用更宽的色彩空间BT2020&#xff0c;提供极致画质体验。从Android10开始&#xff0c;支持HDR视频播放。 一、HDR技术 HDR技术标准包括&#xff1a;Dolby-Vision、HDR10、HLG、PQ。支持…

set与map

set与map 一、序列式容器与关联式容器二、pair1、键值对2、作用3、构造函数4、make_pair&#xff08;1&#xff09;构造函数&#xff08;2&#xff09;作用 5、代码6、运行结果 三、set1、概念2、代码3、运行结果4、说明 四、multiset1、与set的关系2、代码3、运行结果 五、map…

鸿蒙系统扫盲(三):鸿蒙开发用什么语言?

1.两种开发方向 我们常说鸿蒙开发&#xff0c;但是其实鸿蒙开发分为两个方向&#xff1a; 一个是系统级别的开发&#xff0c;比如驱动&#xff0c;内核和框架层的开发&#xff0c;这种开发以C/C为主 还有一个是应用级别的开发&#xff0c;在API7以及以下&#xff0c;还是支持…

linux socket套接字

文章目录 socket流socket&#xff08;TCP&#xff09;数据报socket&#xff08;UDP&#xff09; 讨论 socket 所谓套接字&#xff0c;就是对网络中不同主机上的应用程序之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端&#xff0c;套接字提供了应用层进程利…

WS2812灯条基于WLED开源项目无门槛使用简介

WS2812灯条基于WLED开源项目无门槛使用简介 &#x1f4cc;项目github地址&#xff1a;https://github.com/Aircoookie/WLED&#x1f4cd;WLED详情地址&#xff1a;https://kno.wled.ge/&#x1f388;网页在线烧录固件地址&#xff1a;https://install.wled.me/ ✨ 仅作为使用的…

【同一局域网下】访问其他电脑的虚拟机

一、在被连接的电脑上对VMware进行设置 编辑 --> 虚拟网络编辑器 按顺序点击 如果22端口已被占用&#xff0c;可以自行定义 &#xff08;端口号越大&#xff0c;被占用的可能性越小&#xff09; 二、在被连接的电脑上对防火墙进行设置&#xff08;这里以win11为例&#xff…

【Qt之QSqlRelationalDelegate】描述及使用

描述 QSqlRelationalDelegate类提供了一个委托&#xff0c;用于显示和编辑来自QSqlRelationalTableModel的数据。 与默认委托不同&#xff0c;QSqlRelationalDelegate为作为其他表的外键的字段提供了一个组合框。 要使用该类&#xff0c;只需在带有QSqlRelationalDelegate实例…

考虑极端天气线路脆弱性的配电网分布式电源配置优化模型_IEEE33节点(附带Matlab代码)

随着新能源技术及智能电网的发展&#xff0c;越来越多的分布式电源加入配电网中&#xff0c;不仅改变了配电网结构及供电方式&#xff0c;而且提升了配电网的供电质量。但是在全球气候变暖的背景下&#xff0c;极端天气发生的频率也越来越高&#xff0c;一旦发生必将对配电网系…

竞赛选题 题目:基于深度学习的中文汉字识别 - 深度学习 卷积神经网络 机器视觉 OCR

文章目录 0 简介1 数据集合2 网络构建3 模型训练4 模型性能评估5 文字预测6 最后 0 简介 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的中文汉字识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &a…

python接口自动化测试之requests库的基础使用

简单介绍 requests库简单易用的HTTP库 Get请求 格式&#xff1a; requests.get(url) 注意&#xff1a;若需要传请求参数&#xff0c;可直接在 url 最后的 ? 后面&#xff0c;也可以调用 get() 时多加一个参数 params &#xff0c;传入请求参数&#xff0c;注意需要是 dict…

如何利用轮廓系数(Silhouette Coefficient)来判断模糊c均值聚类FCM的聚类簇数量

文章目录 前言一、轮廓系数的计算方法二、具体流程 前言 轮廓系数&#xff08;Silhouette Coefficient&#xff09;是一种评价聚类效果的指标&#xff0c;它可以用于判断模糊C均值聚类的聚类簇数量。 一、轮廓系数的计算方法 对于每个数据点i&#xff0c;计算它属于每个聚类…

【GraphQL】什么是Prisma?

本页提供了Prisma及其工作原理的高级概述。 什么是Prisma&#xff1f; Prisma是一个开源的下一代ORM。它由以下部分组成&#xff1a; Prisma客户端&#xff1a;Node.js和TypeScript的自动生成和类型安全查询生成器Prisma迁移&#xff1a;迁移系统Prisma Studio:GUI&#xff0…