蓝桥杯之《开心的金明》——基于动态规划的滚动数组

--------滚动数组及动态规划思想--------

滚动数组·减少空间复杂度:在一些题目中,可能需要数组去记录一些过程,但有些时候,我们最后的结果并不需要得到这些中间过程,而是利用这些过程最终得到需要的结果,这是我们就可以利用滚动数组的思想重复利用那些不需要的数组数据,将新的过程数据放到那些数组空间中去。

不恰当演示如下:

在这里插入图片描述

动态规划·空间换时间:我的理解为每个阶段的最优状态可以从之前阶段的基础上计算得到,具体可以看大佬们的解释或者B站算法很美(极力推荐,我是从那里学的,给出的常见动规题目类型解析很多,此外还有其他算法),我怕解释错了误导大家(狗头护体,算法资源链接:《算法很美》之动态规划

---------------------------------------分·割·线-----------------------------------------

-----------此题题解-----------

完整题目:

在这里插入图片描述

完整通过代码

*#include<iostream>
using namespace std;
struct thing//建立物品信息结构体
{
	int pri;//物品价格
	int lev;//物品重要度
};
int main()
{ 
	int summoney,sumthin;//拥有的总钱数及总物品数
	int dp[2][30005]={0};//建立DP表,纵坐标代表钱数
	int maxv=0;//用于记录物品乘以重要度累计和最大值
	struct thing thi[30];
	cin>>summoney>>sumthin;
	for(int i=0;i<sumthin;i++)
	{
		cin>>thi[i].pri>>thi[i].lev;
	}
	for(int i=1;i<=summoney;i++)
	{
		if(i>=thi[0].pri)
		{
			dp[0][i]=thi[0].lev*thi[0].pri;//DP表中存储的是当前拥有的钱可以获得的最大物品乘以重要度的累计和
		}
	}
	for(int i=1;i<sumthin;i++)//遍历所有物品试探买与不买获得的最大累计和
	{
		for(int j=1,s=0,t=0;j<=summoney;j++)
		{
			s=0;
			if(j>=thi[i].pri)//如果剩余钱数大于此物品数则可以选择买它
			{
				t=j-thi[i].pri;//如果买了该物品后剩余的钱
				s=thi[i].lev*thi[i].pri+dp[(i-1)%2][t];
				dp[i%2][j]=s>dp[(i-1)%2][j]?s:dp[(i-1)%2][j];//比较买它和不买它能得到的最大累计和
			}
			else
			{
				dp[i%2][j]=dp[(i-1)%2][j];//不能买它则直接存储得到上一阶段的值
			}
			maxv=maxv>dp[i%2][j]?maxv:dp[i%2][j];//更新最大累计和
		}
	}
	cout<<maxv;
	return 0;
}*

--------------------------------------总结分割线--------------------------------------

以上为鄙人拙见,若有错误或建议,还请不吝指出,若有需要解释的

地方,可以私信或者QQ联系(个人资料有,非诚勿扰,感谢)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值