装船问题

装船问题

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem 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

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

Sample Input

100
10 10
20 10
30 10
40 10
50 10
60 10
70 10
80 10
90 10
100 10

Sample Output

550

Hint

价重比:计算其价值与重量之比

 

 

 

 

#include <stdio.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;
struct node
{
    int pi;
    int pw;
    int wi;
}num[15], t;

int main()
{
    int M, i, j, k;
    cin >> M;
    for(i = 0; i < 10; i++)
    {
        cin >> num[i].pi >> num[i].wi;
        num[i].pw = num[i].pi / num[i].wi;
    }
    for(i = 0; i < 9; i++)
    {
        k = i;
        for(j = i+1; j < 10; j++)
        {
            if(num[i].pw < num[j].pw)
            {
                t = num[i];
                num[i] = num[j];
                num[j] = t;
            }
        }
    }
    /*for(i = 0; i < 10; i++)
    {
        cout << num[i].pw <<  endl;
    }*/
    i = 0;
    int cnt = 0;
    int m = M;
    while(i < 10 && m-num[i].wi >= 0)
    {
        cnt += num[i].pi;
        m -= num[i].wi;
        i++;
    }
    if( i<10 ) cnt += num[i].pw*m; //可能m没有装满,剩下的全部装性价比最好的。
    cout << cnt << endl;
    return 0;
}

 

<think>好的,我需要帮用户理解贪心算法在装船问题中的应用和实现。首先,我得回忆装船问题的基本概念,以及贪心算法的原理。装船问题要求在不超过货船最大载重量的情况下,选择货物使得总价值最大。贪心算法在这里的应用通常是基于某种局部最优的选择,比如价重比。 根据用户提供的引用,问题描述是选择若干货物,使得总重量不超过M,而总价重比最大。这里的价重比指的是每单位重量的价值,即p_i/w_i。所以,贪心策略应该是优先选择价重比高的货物,直到载重量用完。 接下来,我需要整理实现步骤。首先计算每种货物的价重比,然后按照这个比例从高到低排序。排序后依次选取货物,直到无法再装下更多的货物。这里需要注意,可能需要部分装载某一种货物,但根据引用中的输入描述,p_i是w_i的整数倍,可能意味着每种货物可以分割,或者必须整件装载?需要仔细看问题要求。 查看引用[4],输入描述中提到p_i是w_i的整数倍,这可能意味着货物可以按整数倍分割,比如如果选择部分重量,价值也按比例计算。但问题输出是整数,所以可能需要全部装载或者不装,但根据价重比的计算方式,可能允许部分装载。不过,根据代码示例中的做法,用户提供的引用[1]提到使用冒泡排序按价重比排序,然后选择货物直到载重用完,可能这里的货物是可以分割的,即可以取部分重量,这样总价值就是按照价重比计算的。比如,如果剩余载重不足以装下全部某货物,就装部分,此时价值为剩余载重乘以价重比。 然后,实现步骤包括计算价重比、排序、贪心选择。代码中的排序部分引用[1]指出冒泡排序效率低,建议改用快速排序,但装船问题中货物种类固定为10种,所以冒泡排序可能足够,但作为一般情况可能需要更高效的算法。 用户可能想知道具体的实现代码,但根据问题中的引用,代码示例中的结构可能涉及结构体存储货物信息,计算价重比,排序,然后遍历。例如,定义一个货物结构体,包含p、w、c(价重比),然后排序,再累加。 需要注意的问题包括排序的正确性,如何处理剩余载重,以及是否允许部分装载。根据引用中的问题描述,输出是最大价值,而输入中的p_i是w_i的整数倍,可能允许部分装载,但需要确认。例如,若货物A有w=2吨,p=4,价重比2。如果剩余载重为1吨,那么可以装0.5个货物A,得到价值1吨×2=2。但根据输入p_i是w_i的整数倍,这样分割后价值可能还是整数。 在代码实现中,引用[1]提到使用冒泡排序,但可以优化为快速排序。因此,在示例代码中,可能使用快速排序来提高效率,尤其是当货物种类较多时。 总结回答的结构应该是:问题描述、贪心策略(按价重比排序)、实现步骤、代码示例、优化建议、应用场景,以及潜在问题和注意事项。同时,生成相关问题,如与其他算法对比、时间复杂度和处理不可分割货物的情况等。 需要确保所有数学公式用$...$,比如价重比表示为$c_i = \frac{p_i}{w_i}$,独立公式用$$...$$。例如,总价值的计算公式可能需要单独成段。 最后,根据引用中的信息,正确添加引用标记,如引用[1]提到使用冒泡排序,可以将其放在对应段落末尾。同时,确保回答使用中文,代码语法正确,结构清晰。</think>### 贪心算法在装船问题中的实现与应用 #### 一、问题描述 装船问题要求从$N$种货物中挑选若干吨装入货轮,**总重量不超过$M$吨**,且**总价值最大化**。引用中明确说明,货物可分割(因$p_i$是$w_i$的整数倍),因此允许选择部分货物[^4]。 #### 二、贪心策略设计 贪心算法的核心是**价重比优先**,即优先选择$\text{价重比} = \frac{\text{价值}}{\text{重量}}$最高的货物。这一策略的数学表示为: $$c_i = \frac{p_i}{w_i}$$ 通过按$c_i$降序排序,逐步装载直至载重$M$耗尽[^1]。 #### 三、实现步骤 1. **计算价重比**:遍历所有货物,计算$c_i = p_i / w_i$ 2. **排序**:按$c_i$从高到低对货物排序(冒泡排序或更优算法) 3. **贪心选择**:依次装载货物,若当前货物重量$\leq$剩余载重,则全装;否则装部分[^3] #### 四、代码实现(Python) ```python def load_ship(M, goods): # 计算价重比并排序 sorted_goods = sorted(goods, key=lambda x: x[0]/x[1], reverse=True) total_value = 0 remaining = M for p, w in sorted_goods: if remaining >= w: total_value += p remaining -= w else: total_value += (p / w) * remaining break # 载重已满 return int(total_value) # 因p_i是w_i整数倍,结果必为整数 # 示例输入:M=100, goods格式为[(p1, w1), (p2, w2), ...] print(load_ship(100, [(60, 10), (120, 30), (100, 20)])) # 输出:240 ``` #### 五、优化与注意事项 1. **排序效率**:当$N$较大时,冒泡排序$O(n^2)$效率低,可改用快速排序$O(n \log n)$[^1] 2. **输入约束**:$p_i$是$w_i$的整数倍,确保部分装载时价值仍为整数 3. **空间优化**:无需存储完整结构体,直接使用元组排序 #### 六、应用场景 1. 物流运输中的**集装箱装载优化** 2. 资源分配问题(如云计算资源调度) 3. 背包问题的简化版本(可分割物品)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值