hun暑期实训 最大报销额(01背包) 关于动态内存分配的new与delete

题目

在这里插入图片描述

思路

这个题主的难点要有三个方面。
第一个方面是数据不好输入。题目中所给的数据都是做题需要的数据,而且是需要分开存储的。对于字母:数字的格式输入,我们可以采用scanf的格式化输入来完成,从而实现,字母、数字分开操作;
第二个方面就是01背包的问题,这个题目给出的数据全是小数,而01背包的一维数组类型需要对背包内存Q进行逆序循环,从而要求是整数,由于题中所给出的小数都是两位数的,所以我们可以将它们×100再进行运算;
第三个方面是01背包问题中一维数组创立的问题,显然这个一维数组是不能用容器vector来代替的(想想为什么?),而题中所给的Q×100后可以会达到十万级别,但是有时的Q不排除较小的情况,这样一来,我们对于一维数组申请内存就不太好操作,过大可能会超出限度,过小会导致越界。因此我们需要用new与delete来动态分配内存。

AC代码1

#include <bits/stdc++.h>
using namespace std;
char type;
double d_price, d_Q;
int n, num;
string s;

vector<int> v;
int main() {
	while (true) {
		v.clear();
		cin >> d_Q >> num;//Q是允许的报销额 num是发票张数
		if (num == 0)
			return 0;//等于0就直接退出
		for (int j = 1; j <= num; ++j) {//有几张发票 一张一张的计算
			int sum = 0;
			cin >> n; //发票上的物件儿数
			for (int i = 1; i <= n; ++i) {
				scanf(" %c:%lf", &type, &d_price);
				int price = d_price * 100;//转为整数
				if ((type == 'A' || type == 'B' || type == 'C') && price <= 60000) {
					//满足四种条件才能相加
					sum += price;
				} else {
					sum = 0;
					getline(cin, s); //如果有不符合的后面的数据直接当作字符串输入不使用
					break;//然后直接用下一张发票
				}
			}
			if (sum != 0 && sum <= 100000)
				v.push_back(sum);
		}
		int len = v.size(), Q = d_Q * 100; //v是存放对应金额的容器
		int *dp;
		dp = new int[Q + 1];//可以用变量来声明大小
		for (int i = 0; i <= Q; ++i) {
			dp[i] = 0;
		}
		for (int i = 0; i < len; ++i) {
			for (int j = Q; j >= 1; --j) {
				if (v[i] <= j) { //可以放进去
					dp[j] = max(dp[j], dp[j - v[i]] + v[i]);;
				}
			}
		}
		printf("%.2lf\n", dp[Q] / 100.0);
		delete[] dp;//释放一组内存
	}
}

AC代码2

//最大报销额
#include <bits/stdc++.h>
using namespace std;
int arr[50];

int main() {
	double Q, price;
	int N, d_price;
	char c;//代表发票的种类
	while (cin >> Q >> N, N != 0) {
		int max_ = 0;
		int len = 1;
		memset(arr, 0, sizeof(arr));
		int d_Q = Q * 100; //0 1背包问题要遍历Q
		for (int s = 0; s < N; ++s) {
			int sum = 0;
			int num;//这是每张发票里面的物品数
			cin >> num;
			for (int j = 0; j < num; ++j) {
				scanf(" %c:%lf", &c, &price);
				//cout << c << " " << price << endl;
				d_price = price * 100;
				if ((c == 'A' || c == 'B' || c == 'C') && d_price <= 60000) {
					sum += d_price;
				} else {
					sum = 0;
					break;
				}
			}
			if (sum != 0 && sum <= 100000)
				arr[len++] = sum;
		}
		int *dp;
		dp = new int [d_Q + 1];
		//开始dp
		for (int k = 0; k < d_Q; ++k) {
			dp[k] = 0;
		}
		for (int i = 1; i <= len; ++i) {
			for (int j = d_Q; j >= arr[i]; --j) {
				dp[j] = max(dp[j], dp[j - arr[i]] + arr[i]);
				max_ = max(max_, dp[j]);
			}
		}
		printf("%.2lf\n", max_ / 100.0);
		delete[] dp;
	}
}

new与delete

C++使用了new与delete来操控内存的释放问题。比C语言的malloc/alloc/realloc和free更好用,可以对类对象调用初始化构造函数或者销毁析构函数。(在堆存储区,向操作系统申请内存)申请完内存后,要用delete还给操作系统,不能一直占据。
由于静态数组的大小只能是常量,不能是变量,在做一些题的时候并不是十分方便,所以我们会使用动态数组来定义符合自己需要长度的数组,这时的动态数组是支持变量来定义大小的。只是我们需要用指针来定义它,要手动来释放它、手动来初始化它内部的值。
但是在DevC++中,我们可以使用变量来声明一个静态数组,在vs code中却不行,也挺玄乎的喔~
所以还是好好地规范使用new与delete吧。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一袍清酒付825

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值