1000. Minimum Weight

本文介绍了一种计算给定权重列表所构成的加权二叉树中最小权值的方法,通过类似哈夫曼树的构造过程,实现对最小非根节点权值之和的求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Given a list of weights w1, w2, ..., wn, we can construct a binary tree with n leaves, where each leaf is marked with one weight. The is called a weighted binary tree. The weight of the tree is w1l1 + w2l2+ ... wnln,  where li is  the height of the leaf with weight wi 

For a given list of weights, there are many weighted trees with these weights. However, different weighted tree will have different weights. You are asked to write a program to find the mimimum weight among those weighted trees for a given list of weights.

 

Input

The first line is the number  n of test cases.

The next n lines are the test cases. Each test case is a list of weights that are positive numbers separated by spaces  followed by the number 0, which signals the end of the weights.  

Output

Each line outputs the minimum weight for the test case.


题目思想为构造哈夫曼树的思想,不过此题不需要生成哈夫曼树,只需要计算出哈夫曼树中的非根结点权值之和即可。

<pre name="code" class="cpp" style="color: rgb(51, 51, 51); font-size: 16px; line-height: 20px;">#include <iostream>
#include <vector>
using namespace std;

//对vector容器进行冒泡排序
void sorts(vector<int> &a) {
    for (int i = 1; i < a.size(); ++i) {
        for (int j = 0; j < a.size() - i; ++j) {
            if (a[j] > a[j+1]) {
                int t = a[j];
                a[j] = a[j+1];
                a[j+1] = t;
            }
        }
    }
}

//构造哈夫曼树,将排序后的数组的前两个元素去除,将前两个元素的和push进数组并排序
void resort(vector<int> &a, int b) {
    const unsigned long count = a.size();
    for (int i = 0; i < count - 2 ; ++i) {
        a[i] = a[i+2];
    }
    a.pop_back();
    a.pop_back();
    a.push_back(b);
    sorts(a);
}

void minW(vector<int> a) {
    sorts(a);
    int sum = 0;
    while (a.size() != 1) {
        int temp = a[0] + a[1];
        //计算总权值
        sum += temp;
        resort(a, temp);
    }
    cout << sum << endl;
}

int main(int argc, const char * argv[]) {
    int cases;
    cin >> cases;
    for (int i = 0; i < cases; ++i) {
        vector<int> weights;
        int temp;
        while (1) {
            cin >> temp;
            if (temp != 0) {
                weights.push_back(temp);
            }
        else break;
        }
        minW(weights);
    }
}

 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值