贪心刷题1-部分背包

本文介绍了如何使用贪心算法解决部分背包问题,通过按价值与重量比率排序金币堆,逐个尝试加入背包,直至背包满载或无法再装。C++代码详细展示了整个过程。
摘要由CSDN通过智能技术生成

题目来源:【深基12.例1】部分背包问题 - 洛谷

参考书目:《深入浅出程序设计竞赛(基础篇)》

解题思路:这道题是部分背包,如果金币不能完整的放入是可以分割的。题目中有若干堆金币,每堆金币有一定的重量(m)和价值(v),以及一个最大承重为 t 的背包。目标是通过完全或部分地拿取这些金币堆,使得背包中的金币价值最大化。代码采用贪心算法,通过按价值与重量比降序排序金币堆,然后迭代地将它们添加到背包中,直到背包装满或没有更多的金币堆可考虑。

解题步骤:

  • 迭代读取每堆金币的重量和价值,并存储在数组 a 中。
  • 使用 sort 函数和 cmp 比较函数对金币堆进行排序。
  • 迭代地将每堆金币加入背包:
    • 如果当前金币堆的重量大于剩余容量,则跳出循环。
    • 否则,从剩余容量中减去金币堆的重量,并将其价值加到总价值 ans 上。
  • 如果因为一堆金币无法完全加入而退出循环,将该金币堆的一部分加入到 ans 中,以填满剩余容量。
  • 最后,打印出总价值 ans,保留两位小数。
#include<iostream>
#include<algorithm>

using namespace std;

// 定义结构体来存储每堆金币的重量和价值
struct coin {
	int m, v; // 金币堆的重量和价值
} a[110];

// 比较函数,用于根据价值与重量的比率(性价比)进行排序
bool cmp(coin x, coin y)
{
	return x.v * y.m > y.v * x.m; // 比较两堆金币的性价比
}

int main()
{
	int n, t, c, i;
	float ans = 0; // 初始化答案变量
	cin >> n >> t; // 读入金币堆数和背包容量
	c = t; // 背包剩余容量初始化为背包总容量
	// 读入每堆金币的重量和价值
	for (i = 0; i < n; i++)
	{
		cin >> a[i].m >> a[i].v;
	}

	// 对金币堆按性价比降序排序
	sort(a, a + n, cmp);

	// 遍历金币堆,尝试将它们加入背包
	for (i = 0; i < n; i++)
	{
		if (a[i].m > c) break; // 如果当前金币堆无法完全装入背包,则跳出循环
		c -= a[i].m; // 减少背包剩余容量
		ans += a[i].v; // 增加背包中金币的总价值
	}

	// 如果退出循环是因为一堆金币无法完全加入,则加入这堆金币的一部分
	if (i < n)
	{
		ans += 1.0 * c / a[i].m * a[i].v; // 加入部分金币堆,按比例计算价值
	}
	// 输出最终答案,保留两位小数
	printf("%.2lf", ans);

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值