【Day4】阅读趣学算法

14天阅读挑战赛
努力是为了不平庸~

算法实例——0/1背包问题

题目描述

有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

在这里插入图片描述

问题分析

  1. 目标函数:∑pi最大,使装入背包的所有物品p的价值加起来最大。
  2. 约束条件:装入的物品总重量不能超过背包容量:∑wi<=M( M=150)
  3. 贪心策略:
    (1)选择价值最大的物品
    (2)选择重量最小的物品
    (3)选择单位重量价值最大的物品

做题思路(三种策略)

策略一:选择价值最大的物品

根据这个策略最终选择装入背包的物品依次是D、B、F、E,此时包的总重量是130,总价值是165。

代码实现:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std; 
//定义待选物体的结构体类型
struct node
{
	double w;//重量 
	double v;//价值 
} we[100] ;

//定义背包问题
bool cmp1(node a ,node b)//价值
{
	if(a.v==b.v)
		return a.w<b.w;
	return a.v>b.v;
}
//将已经确定要装入背包的物品装入 
int fun1(int n,int c)
{
	sort(we,we+n,cmp1);
	int value=0;
	for(int i=0; i<n; i++)
	{
		if(c>=we[i].w)
		{
			c-=we[i].w;
			value+=we[i].v;
		}
	}
	return value;
}
int main(void)
{
	int n,c,sum;//n个物品,c的容量,sum的价值 
	cin>>n>>c;
	for(int i=0; i<n; i++)
		cin>>we[i].w;
	for(int j=0; j<n; j++)
		cin>>we[j].v;
	sum=fun1(n,c);
	cout<<sum<<endl;
}

测试结果:

7 150
35 30 60 50 40 10 25
10 40 30 50 35 40 30
165

--------------------------------
Process exited after 28.52 seconds with return value 0
请按任意键继续. . .

注意:在用sort进行排序时,要加入头文件"algorithm"。

策略二:选择重量最小的物品

根据这个策略最终选择装入背包的物品编号依次是 F、G、B、A、E,此时包中物品总重量是 140,总价值是 155。

代码实现:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std; 
//定义待选物体的结构体类型
struct node
{
	double w;//重量 
	double v;//价值 
} we[100] ;

//定义背包问题
bool cmp2(node a ,node b)//重量 
{
	if(a.w==b.w)
		return a.v>b.v;
	return a.w<b.w;
}
//将已经确定要装入背包的物品装入 
int fun2(int n,int c)
{
	sort(we,we+n,cmp2);
	int value=0;
	for(int i=0; i<n; i++)
	{
		if(c>=we[i].w)
		{
			c-=we[i].w;
			value+=we[i].v;
		}
	}
	return value;
}
int main(void)
{
	int n,c,sum;//n个物品,c的容量,sum的价值 
	cin>>n>>c;
	for(int i=0; i<n; i++)
		cin>>we[i].w;
	for(int j=0; j<n; j++)
		cin>>we[j].v;
	sum=fun2(n,c);
	cout<<sum<<endl;
}

测试结果:

7 150
35 30 60 50 40 10 25
10 40 30 50 35 40 30
155

--------------------------------
Process exited after 28.52 seconds with return value 0
请按任意键继续. . .

策略三:选择单位重量价值最大的物品

物品的价值密度 si 定义为 pi/wi,这 7 件物品的价值密度分别为 si=[0.286,1.333,0.5,1.0,0.875,4.0,1.2]。根据这个策略最终选择装入背包的物品编号依次是 F、B、G、D、A,此时包中物品的总重量是 150,总价值是 170。

** 代码实现:**

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std; 
//定义待选物体的结构体类型
struct node
{
	double w;//重量 
	double v;//价值 
} we[100] ;

//定义背包问题
bool cmp3(node a,node b)// 单位价值
{
	if((a.v/a.w)==(b.v/b.w))
		return a.w<b.w;
	return (a.v/a.w)>(b.v/b.w);
}
//将已经确定要装入背包的物品装入 
int fun3(int n,int c)
{
	sort(we,we+n,cmp3);
	int value=0;
	for(int i=0; i<n; i++)
	{
		if(c>=we[i].w)
		{
			c-=we[i].w;
			value+=we[i].v;
		}
	}
	return value;
}
int main(void)
{
	int n,c,sum;//n个物品,c的容量,sum的价值 
	cin>>n>>c;
	for(int i=0; i<n; i++)
		cin>>we[i].w;
	for(int j=0; j<n; j++)
		cin>>we[j].v;
	sum=fun3(n,c);
	cout<<sum<<endl;
}
7 150
35 30 60 50 40 10 25
10 40 30 50 35 40 30
170

--------------------------------
Process exited after 166.5 seconds with return value 0
请按任意键继续. . .

总结

0/1背包问题的贪心算法的三个策略不一样,但实现的过程都是类似的,都是通过选择当前看上去最好的一个方案,在一定条件下,贪心算法是0/1背包问题的较好的算法,但不是所有0/1背包问题都可以通过贪心算法找到最优解,只能通过贪心算法求得局部最优解,而涉及到贪心无法解决的0/1背包问题,这时就要用动态规化等算法来解决。

继续加油,学习更多有趣的算法!如有问题请指出,新手创作,如有帮助请给个赞!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

开摆C

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

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

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

打赏作者

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

抵扣说明:

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

余额充值