蓝桥杯:合并果子

一、题目

有n种类的果子,每个果子重量均为1。每一种类各有不同数量的果子,由输入决定该数量,每一类果子堆一堆。果农需要通过搬运把所有果子合并,每一次搬运合并两堆果子,直到只剩一堆,共需要搬运n-1次。每次搬运消耗的体力是两堆果子的重量之和。求最少搬运体力。

https://www.lanqiao.cn/problems/741/learning/

二、分析

搬运n-1次,每次需要找出最轻的两堆果子,然后计算体力。接着两堆果子的重量之和需要作为一堆新的果子看待,重回搬运数组中参与下一轮搬运。直到只剩一堆。

算法:贪心算法,或者优先队列

三、代码

运用数组weight代表果子重量,数组move代表果子是否已经搬运。

#include <iostream>
#include <cmath>

using namespace std;

int indiff = pow(2,31);
int main() {
    int n;  // 种类
    cin >> n;
    while (n < 1 || n > 10000) {
        cout << "n的范围需要在1~10000(包含)以内,请重新输入:";
        cin >> n;
    }

    // 不同种类果子的重量
    //vector<int> weight;
    int* weight = new int[n];
    bool* move = new bool[n]; // 果子是否已经搬运
    for (int i = 0; i < n; i++) {
        cin >> weight[i];
        while (weight[i] >= pow(2, 31)) {
            cin >> weight[i];
        }
        move[i] = 0;
    }

    int consume = 0; // 耗费体力
    int min_1, min_2; // 最小的两堆果子的重量
    min_1 = indiff;
    min_2 = indiff;
    int index_1 = 0, index_2 = 0; // 对应下标


    for (int i = 0; i < n - 1; i++) {  // n-1次合并
        for (int j = 0; j < n; j++) { // n次比较,找出最小值
            if (move[j])
                continue;
            else if (weight[j] < min_1) { // 未搬运,且最小
                    min_2 = min_1;
                    index_2 = index_1;

                    min_1 = weight[j];
                    index_1 = j;
                 }
            else if (weight[j] < min_2) {
                min_2 = weight[j];
                index_2 = j;
            }
        }
        // 搬运合并
        consume = consume + min_1 + min_2;
        weight[index_1] = min_1 + min_2;
        move[index_2] = true;
        min_1 = indiff;
        min_2 = indiff;
    }

    cout << consume;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值