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]);,这样代码更简洁。