实验二:动态规划

news2025/7/31 23:48:21

1.双11的红包雨

问题描述

双11到了,据说这2天会下红包雨,每个红包有不同的价值,小k好开心,但有个规则,就只能接掉落在他身旁的10米范围内的红包(0-10这11个位置)。小k想尽可能的多抢红包,这样就可以去买一个华为手机,小k每秒种只能在移动不超过一米的范围内接住红包。小k一开始站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的红包。问小k最多可能接到多少价值的红包?

输入

第一行输入整数n,表示共有多少个红包,n<1000;

后面n行表示n个红包,每行有三个整数,分别表示红包掉落的位置、时间和价值。

输出

小k接到的红包价值之和。

输入样例

8
3 18 5
7 13 7
1 8 10
2 7 13
10 20 1
3 17 8
10 2 123
3 13 45

输出样例

81

每个时刻的状态只有三种

  1. 继续站在原地

  2. 向左移动

  3. 向右移动

    此外还要注意一点,在0处不能向左移动,在11处不能向右移动。

    状态转移方程
    d p [ i ] [ j ] = m a x n ( d p [ i + 1 ] [ j − 1 ] , d p [ i + 1 ] [ j ] , d p [ i + 1 ] [ j + 1 ] ) + d p [ i ] [ j ] dp[i][j]=maxn(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])+dp[i][j] dp[i][j]=maxn(dp[i+1][j1]dp[i+1][j]dp[i+1][j+1])+dp[i][j]

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

int dp[1010][12];  // dp[i][j]表示i时刻j位置开始出发,到最终时间点所获得的最大红包数
//两个数中的最大值
int max_2(int a, int b)
{
	return (a>b) ? a :b;
}
//三个数中的最大值
int maxn(int a, int b, int c)
{
	int max = (a>b) ? a : b;
	return (max>c) ? max : c;
}
// 计算最优值
// 状态转移方程为:dp[i][j]=maxn(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])
void maxValue(int max_time)
{
    //对于每个时间所有位置从结束计算到开头
    //当记录了上一时刻的最大值,可以以此为参照,计算出所有位置该时刻的最大值
    //两重循环之后可以获取所有位置所有时刻的最大值
	for(int i=max_time-1; i>=0; i--)
    {
		for(int j=0; j<12; j++)
        {
			if(j == 0)  // 在第0位置,下一秒只能原地或向右移动 
				dp[i][j] = max_2(dp[i+1][j],dp[i+1][j+1]) + dp[i][j];
			else if(j == 11)   // 在第11位置,下一秒只能原地或向左移动 
				dp[i][j] = max_2(dp[i+1][j],dp[i+1][j-1]) + dp[i][j];
			else
                // 其他情况,每个时刻能够向左右或者不动
				dp[i][j] = maxn(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])+ dp[i][j];
		}
	}
}
int main()
{
	int n;
	cin >> n;
	int location, time, value;
	int max_time = -1;
	memset(dp, 0, sizeof(dp));
	// 保存输入的数据到数组中 
	while(n--)
    {
		cin >> location >> time >> value;
		dp[time][location] = value;
		if(time > max_time) max_time = time;
	}
    // 求出最大的红包
	maxValue(max_time);
    // dp[1][4]为初始时刻、初始位置对应的价值,已经从最后时刻推回来了,所以一定是最优解。
	cout << dp[1][4] << endl;
	return 0;
}

2.最大连续字段和

问题描述:略

只有两种情况:

  1. 某位置最大连续子段为它本身
  2. 最大连续子段长度至少为 2(至少包含它之前的一个节点)

取两者的最大值,递推方程:
d p [ i ] = m a x ( d p [ i − 1 ] + a r r [ i ] , a r r [ j ] ) dp[i]=max(dp[i-1]+arr[i],arr[j]) dp[i]=max(dp[i1]+arr[i],arr[j])

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int num;
	cin>>num;
	int arr[num],dp[num]; 
	// 读数据
    for(int i=0;i<num;i++)
    { 
		cin>>arr[i];dp[i]=0;
	}
    // 初始化
	dp[0]=max(arr[0],0);
	for(int i=1;i<num;i++)
    {
        // 状态转移方程
		dp[i]=max(arr[i],dp[i-1]+arr[i]); 
	}
	sort(dp,dp+num);//排序
	cout<<dp[num-1];//输出最大值 
	return 0;
}

3.减肥的小k 2

题目描述

小K是个苦命的孩子,他的师傅为了多赚钱,以减肥为理由,让他去采药,并说不完成不能吃饭。野地里有许多不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。要求在规定的时间t里,采到的草药的总价值最大。

输入

第一行有2个整数T(1≤T≤1000)和M(1≤M≤100),一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。

输出

1个整数,表示在规定的时间内可以采到的草药的最大总价值。

输入样例

70 3
71 100
69 1
1 2

输出样例

3

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005; // 最大草药数量
const int MAXT = 1005; // 最大采药时间
int t[MAXN], v[MAXN];  // t[i]是第i个草药的采摘时间,v[i]是第i个草药的价值
int dp[MAXT];          // dp[j]表示用j的时间采摘草药的最大价值
int main()
{
    int T, M;
    cin >> T >> M; // T是总时间,M是草药数量
    for (int i = 1; i <= M; i++)
    {
        cin >> t[i] >> v[i]; // 输入每个草药的采摘时间和价值
    }
    memset(dp, 0, sizeof(dp)); // 初始化dp数组为0
    for (int i = 1; i <= M; i++)
    {
        for (int j = T; j >= t[i]; j--)
        {// 从后往前遍历,防止重复计算
            dp[j] = max(dp[j], dp[j-t[i]]+v[i]); // 状态转移方程
        }
    }
    cout << dp[T] << endl; // 输出用T的时间采摘草药的最大价值
    return 0;
}

4.最长非连续公共子序列

题目描述

dp [ i ] [ j ] 表示第一个串前 i 个与第二个串前 j 个组成的 lcs 子问题

状态转移方程:

如果当前指针两个字符相同:
d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 dp[i][j] = dp[i-1][j-1] + 1 dp[i][j]=dp[i1][j1]+1
如果当前指针两个字符不同:

需要从前面的两个状态恢复,两个状态分别为 dp [ i-1 ] [ j ] 和 dp [ i ] [ j-1 ] ,将它们的最大值作为该位置的状态
d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) dp[i][j] = max(dp[i-1][j], dp[i][j-1]) dp[i][j]=max(dp[i1][j],dp[i][j1])

#include<bits/stdc++.h>
using namespace std;
int lcs(string s1, string s2) 
{
    // 初始化
    int m = s1.size();
    int n = s2.size();
    int dp[m+1][n+1];
    memset(dp, 0, sizeof(dp));
    // 对于a,b两个字符串,分别设定两个指针a,b
    // 指针分别从头开始向后移动,取两个字符串前i,j个
    // 这样就存在两种情况
    // 1.两个指针处的字符相同说明存在子串,dp[i][j] = dp[i-1][j-1] + 1 从ab指针同时退后两个的情况+1
    // 2.如果两个指针指向的字符不相同,说明不能从 i-1,j-1 跳转到 i,j,但是为了保存之前的结果,需要存储当前
    // 的最优解,当前是将两个指针同时前进1个单位,最优解一定在左指针前进一个或右指针前进一个里面选
    // 这就推出了最终的状态转移方程
    for (int i = 1; i <= m; i++) 
    {
        for (int j = 1; j <= n; j++) 
        {
            if (s1[i-1] == s2[j-1]) 
            {
                dp[i][j] = dp[i-1][j-1] + 1;
            }
            else
            {
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
            }
        }
    }
    return dp[m][n];
}
int main() 
{
    string s1 = "ABCD";
    string s2 = "ABDE";
    cout << lcs(s1, s2) << endl;  // 输出 2,即 "AB" 是最长非连续公共子序列
    return 0;
}

5.切钢条

题目描述

一家公司购买长钢条,将其切割成短钢条出售,切割本身没有成本,长度为i的短钢条的价格为Pi。那给
定一段长度为n的钢条和一个价格表Pi,求钢条的切割方案使得收益Rn最大。

在这里插入图片描述

输入要求

输入钢条的长度n。

输出要求

输出获得的最大收益。

dp [ i ] 表示长度为 i 的情况下的最大利润

共有 10 种切法,所以要设置两重循环,目的是获得每个长度下的最优解,有了小长度才能以此为基础获取大长度的最优解

有两种状态,切或不切,切掉之后要考虑价值是否增加,所以产生了状态转移方程:
d p [ i ] = m a x ( p i [ j ] + d p [ i − j ] , d p [ i ] ) dp[i] = max(pi[j] + dp[i - j], dp[i]) dp[i]=max(pi[j]+dp[ij],dp[i])

#include<bits/stdc++.h>
using namespace std;
int pi[11] = { 0,1,5,8,9,10,17,17,20,24,30 }; //记录已知长度钢条价值
int dp[1000] = { 0 };//记录动态规划结果
int findMaxVal(int n)
{
    if (n == 0) // 若n为0直接返回
        return 0;
    for (int i = 1;i <= n;i++) 
    {
        for (int j = 1;j <= i && j <= 10;j++) 
        { // 第一刀最多切10种
            dp[i] = max(pi[j] + dp[i - j], dp[i]);//遍历所有切法
        }
    }
    return dp[n];
}
int main()
{
    int n;
    cin >> n;
    memset(dp,0,sizeof(dp));
    // 判断一下是否超过10,记录除数和余数
    int chushu = 0;
    int yushu = 0;
    int res_10 = 0;
    int res = 0;
    if(n>10)
    {
        chushu = n / 10;
        yushu = n % 10;
        res_10 = findMaxVal(10);
        res_10 *= chushu;
        res = res_10 + findMaxVal(yushu);
    }
    else
    {
    	res = findMaxVal(n); 
    }
    cout << res << endl;
    return 0;
}

6.合格的盗贼

题目描述

一条街上有N个商铺;商铺i有价值V[i]的物品,你有足够的时间在晚上光顾所有的商店,人们称呼你为盗贼;每个商店都有一个报警器,会在晚上报警,但是只有相邻的2个商店同时报警时,警察才会出动;你需要证明你是个合格的盗贼。

输入要求

第一行一个整数N<=100,商店数。
第二行N个整数,每个商店的价值

输出要求

输出偷盗的最大价值。

假设在考虑第i个,只有两种个情况,只有这两种情况收益最大,按照这种思想往下推很简单就能求出最大利润

  1. 第一种,i,i - 2
  2. 第二种,i - 1
#include<bits/stdc++.h>
using namespace std;
int dp[101] = { 0 };
int findMaxValue(int n)
{
    if (n == 1)
        return dp[0];
    else if (n == 2)
        return max(dp[0], dp[1]);
    dp[1] = max(dp[0], dp[1]);
    for (int i = 3;i <= n;i++)
    {
        // 只有两种选择,假设有 a b c 三个连续的位置
        // 只有两种选择不会触发警报
        // 1. a c
        // 2. b
        // 依据这个限制条件可以给出状态转移方程
        dp[i - 1] = max(dp[i - 2], dp[i - 3] + dp[i - 1]);
    }
    return dp[n - 1];
}
int main()
{
    int n;
    cin >> n;
    for (int i = 0;i < n;i++) 
    {
        cin >> dp[i];
    }
    int res = findMaxValue(n);
    cout << res << endl;
    return 0;
}

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

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

相关文章

评价提高分子对接性能的组合策略

评价提高分子对接性能的组合策略 相关背景&#xff1a; 分子对接可能是应用于基于结构的药物设计和虚拟筛选活动中最快速、成本最低的计算技术&#xff0c;它可以从巨大的化合物文库中找到潜在的活性分子&#xff0c;用于先导发现。 在分子对接中&#xff0c;配体(通常是小分…

LIME: Low-light Image Enhancement viaIllumination Map Estimation

Abstract当人们在低光条件下拍摄图像时&#xff0c;图像通常会受到低能见度的影响。除了降低图像的视觉美感外&#xff0c;这种不良的质量还可能显著降低许多主要为高质量输入而设计的计算机视觉和多媒体算法的性能。在本文中&#xff0c;我们提出了一种简单而有效的微光图像增…

2023年最新的站内SEO指南:如何通过关键词优化提高网站排名

SEO或搜索引擎优化是指通过改善网站的内部和外部元素&#xff0c;以获得更好的自然搜索引擎排名和更多的网站流量。 链接建设和外链是SEO的重要组成部分&#xff0c;因为它们可以提高网站的权威性和可信度&#xff0c;从而使其在搜索引擎中排名更高。 在此指南中&#xff0c;…

MySQL三范式

1、查询语句写的烂2、索引失效&#xff08;数据变更&#xff09;3、关联查询太多join&#xff08;设计缺陷或不得已的需求&#xff09;4、服务器调优及各个参数设置&#xff08;缓冲、线程数等&#xff09; 通常SQL调优过程&#xff1a; 观察&#xff0c;至少跑1天&#xff0…

CF756div3 vp

又被薄纱了&#xff0c;rk就不放了&#xff0c;好丢人QwQDashboard - Codeforces Round 756 (Div. 3) - CodeforcesA. Make Even小分类讨论题意&#xff1a;给定一个数&#xff0c;每次操作可以选取其前缀然后翻转其前缀&#xff0c;问你最少操作几次可以把该数变为偶数思路&am…

基于深度学习的轴承寿命预测实践,开发CNN、融合LSTM/GRU/ATTENTION

关于轴承相关的项目之前做的大都是故障识别诊断类型的&#xff0c;少有涉及回归预测的&#xff0c;周末的时候宅家发现一个轴承寿命加速实验的数据集就想着拿来做一下寿命预测。首先看下数据集如下&#xff1a;直接百度即可搜到&#xff0c;这里就不再赘述了。Learning_set为训…

什么是蜕变测试?

文章目录1.传统测试2.蜕变测试2.1.蜕变测试的理解2.2.蜕变测试的步骤2.2.1.生成蜕变关系2.2.2.生成蜕变用例2.2.3.执行蜕变用例2.2.4.校验蜕变关系参考文献1.传统测试 在没有蜕变测试的时代&#xff0c;传统软件测试的原理是&#xff1a;给定输入&#xff0c;观察被测软件的输…

你把骑行当什么? 它就是你需要的

1.骑行是一种有活力的运动&#xff0c;尝试一下你一定会喜欢上它的&#xff01;2.把骑行当作一种娱乐&#xff0c;让自己快乐地体验自然的美&#xff01;3.骑行可以帮助你改变心态&#xff0c;让你的心情变得更加愉悦&#xff01;4.让骑行成为你每天的计划&#xff0c;看看骑行…

项目实战典型案例27——单表的更新接口有9个之多

单表的更新接口有9个之多一&#xff1a;背景介绍环境准备引入pom依赖配置数据库连接mybatis配置文件Mybatis的配置类编写通用的更新语句可以覆盖的更新接口暂时无法覆盖的接口测试四&#xff1a;总结五&#xff1a;升华一&#xff1a;背景介绍 本篇博客是对项目开发中出现的单…

如何分析sql性能

1、前言 提到sql性能分析&#xff0c;可能都会想到explain&#xff0c;它在mysql里被称为执行计划&#xff0c;也就是说可以通过该命令看出mysql在通过优化器分析之后如何执行sql。mysql的内置优化器十分强大&#xff0c;它能帮我们把sql再次优化&#xff0c;以最低的成本去执…

记录自己开发一款小程序中所遇到的问题(uniapp+uview)(持续更新)

每次开发小程序中&#xff0c;都会遇到各种各样的问题。但是有的问题已经遇到过了&#xff0c;但是遇到的时候还是要各种的问度娘。 特此出这篇文章&#xff0c;方便自己也是方便大家。 仅供参考 1. u-collapse的样式在h5中正常&#xff0c;但是运行到微信小程序中样式就乱了…

滑动窗口求最大和最小

滑动窗口 要区分最小和最大滑窗&#xff0c;内层while循环的条件和更新结果的地方 核心&#xff1a; 关键的区别在于&#xff0c;最大滑窗是在迭代右移右边界的过程中更新结果&#xff0c;而最小滑窗是在迭代右移左边界的过程中更新结果。 最小滑窗 给定数组 nums&#xff0…

成都待慕电商:抖音极速版商品卡免佣扶持政策规则

新规&#xff0c;抖音极速版推出商品卡免佣扶持政策规则&#xff0c;本次抖音规则如何规定&#xff1f;具体往下看&#xff1a;一、政策简介1.1政策介绍为了更好地满足用户消费需求&#xff0c;丰富商家经营模式&#xff0c;降低商家经营成本&#xff0c;现平台针对商品卡场景推…

【数据结构】模拟实现 堆

堆数据结构是一种数组对象&#xff0c;它可以被看作一颗完全二叉树的结构&#xff08;数组是完全二叉树&#xff09;&#xff0c;堆是一种静态结构。堆分为最大堆和最小堆。最大堆&#xff1a;每个父结点都大于孩子结点。最小堆&#xff1a;每个父结点都小于孩子结点。堆的优势…

前端脚手架搭建(part 1)

本篇主要介绍如何搭建前端脚手架&#xff0c;一步一步地实现通过搭建的脚手架下载对应的项目模板。通过脚手架的创建&#xff0c;可以快速搭建项目的基础配置和模板&#xff0c;在部门项目开发的规范中尤其总要。初始化项目&#xff1a;创建一个文件夹&#xff0c;命名随便&…

【LeetCode】螺旋矩阵 [M](数组)

54. 螺旋矩阵 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,…

OceanBase 生态产品:时序数据库CeresDB 正式发布 1.0 版本

欢迎访问OceanBase官网获取更多信息&#xff1a;https://www.oceanbase.com/ CeresDB 是一款拥有计算存储分离架构的分布式时序数据库&#xff0c;其存储层可以基于 OceanBase KV、OSS 等。经过近一年的开源研发工作&#xff0c;CeresDB 1.0 现已正式发布&#xff0c;达到生产…

tcsh常用配置

查看当前的shell类型 在 Linux 的世界中&#xff0c;有着许多 shell 程序。常见的有&#xff1a; Bourne shell (sh) C shell (csh) TC shell (tcsh) Korn shell (ksh) Bourne Again shell (bash) 其中&#xff0c;最常用的就是bash和tcsh&#xff0c;本次文章介绍tcsh的…

HACKTHEBOX——Help

nmap可以看到对外开放了22,80,3000端口可以看到80端口和3000端口都运行着http服务&#xff0c;先从web着手切入TCP/80访问web提示无法连接help.htb&#xff0c;在/etc/hosts中写入IP与域名的映射打开只是一个apache default页面&#xff0c;没什么好看的使用gobuster扫描网站目…

配电室常见6大隐患,你中了几个?

当今社会&#xff0c;电力的重要性不言而喻&#xff0c;在变电站、配电室等一些场景中放置有大量的电气设备。 为保障这些设备正常运行&#xff0c;以免因为这些设备故障导致无法正常进行电力供应&#xff0c;严重影响生产和生活&#xff0c;我们需要运行一套动环监控系统。 配…