贪心算法——装船问题

1.问题

装船问题

Description

王小二毕业后从事船运规划工作,吉祥号货轮的最大载重量为M吨,有10种货物可以装船。第i种货物有wi吨,总价值是pi。王小二的任务是从10种货物中挑选若干吨上船,在满足货物总重量小于等于M的前提下,运走的货物的价重比最大。

Input

输入数据的第一行有一个正整数M(0 < M < 10000),表示所有货物最大载重量。在接下来的10行中,每行有若干个数(中间用空格分开),第i行表示的是第i种货物的货物的总价值pi ,总重量wi。(pi是wi的整数倍,0 < pi , wi < 1000)

Output

输出一个整数,表示可以得到的最大价值。

Samples

Sample #1
Input 
100
10 10
20 10
30 10
40 10
50 10
60 10
70 10
80 10
90 10
100 10

Output 

550

2.代码

#include<bits/stdc++.h>
using namespace std;
const int N=12;
struct node
{
	int p,w;
	int c;
}huo[N],t;
int main()
{
	int m;
	cin>>m;
	for(int i=0;i<10;i++)
	{
		cin>>huo[i].p>>huo[i].w;
		huo[i].c=huo[i].p/huo[i].w;
	}
	for(int i=0;i<9;i++)
	{
		for(int j=i;j<10;j++)
		{
			if(huo[i].c<huo[j].c)
			{
				t=huo[i];//swap(huo[i],huo[j]);
				huo[i]=huo[j];
				huo[j]=t;
			}
		}
	}
	int sum=0;
	for(int i=0;i<10;i++)
	{
		if(huo[i].w<m)
		{
			sum=sum+huo[i].p;
			m=m-huo[i].w;
		}
		else
		{
			sum+=huo[i].c*m;
			break;
		}
	}
	cout<<sum<<endl;
}

3.解析代码

(1)定义结构体:
       struct node 定义了一个节点结构,包含货物的总价值 p、总重量 w 和价重比 c。
(2)读取输入:
       读取最大载重量 M。
       读取每种货物的总价值和总重量,并计算每种货物的价重比。
(3)排序:
       使用冒泡排序对货物按照价重比从大到小排序。这样,价重比最高的货物会排在数组的前面。
(4)贪心选择:
        遍历排序后的货物数组,按照价重比从高到低的顺序选择货物装船。
        如果当前货物的重量小于等于剩余的载重量 m,则将该货物的全部重量装上船,并更新剩余          载重量 m 和总价值 sum。
        如果当前货物的重量大于剩余的载重量 m,则只装上剩余载重量 m 允许的部分,并更新总价          值 sum,然后跳出循环。
(5)输出结果:
         输出可以得到的最大价值。

4.代码原理
这个问题是一个典型的贪心算法问题,因为价重比高的货物单位重量的价值更高,所以应该优先选择价重比高的货物。通过将货物按照价重比排序,可以确保每次选择都是局部最优的,从而得到全局最优解。

5.代码中的关键点
价重比的计算:huo[i].c = huo[i].p / huo[i].w; 计算每种货物的价重比。
冒泡排序:通过冒泡排序对货物按照价重比进行排序。
贪心选择:按照价重比从高到低的顺序选择货物,直到船的载重量用完。
6.代码中的潜在问题
排序效率:冒泡排序的时间复杂度为 O(n^2),在货物种类较多时效率较低。可以考虑使用更高效的排序算法,如快速排序或归并排序。
代码优化:代码中的 t = huo[i]; 可以优化为 swap(huo[i], huo[j]);,这样代码更简洁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值