noj 1076 机器狗组装费用(优先队列)

机器狗组装费用计算算法
本文介绍了一种解决机器狗组装费用最小化问题的算法,包括输入数据处理、使用优先队列实现组装过程以及输出组装所需的最低费用。该算法通过优先处理价格较低的组件来优化组装顺序,从而达到降低整体成本的目的。

机器狗组装费用

时间限制(普通/Java) : 1500 MS/ 4500 MS          运行内存限制 : 65536 KByte
总提交 : 491            测试通过 : 167 

题目描述

sed同学最近迷上了制造机器狗,购置了大量所需零件,零件可以组装为一个组件,这些组件或零件又可以组装为一个大的组件。在制造机器狗中,组件或零件只能两两进行组装,组装的顺序任意。在机器狗中,每个零件都有一个组装成本,每次组装一个组件的费用为各个零件组装成本之和。给定各个零件组装成本(单位为元),你的任务是帮助sed计算他至少花费多少费用。



输入

第一行包括一个整数N,表示机器狗零件数(1≤N≤10000)

第二行为N个正整数,表示每个机器狗零件组装成本(单位为元),整数之间用空格隔开。

输出

输出仅一行,即机器狗组装的最少费用。

注意:输出部分的结尾要求包含一个多余的空行。

样例输入

10
1 2 3 4 5 6 7 8 9 0

样例输出

136


解题思路:要求组装费用最小,每次两个价值最小的相加,再加入总费用中即可,典型优先队列,优先队列默认值大的优先极高,可通过cmp修改优先权。


代码如下:

#include <cstdio>
#include <queue>
using namespace std;

struct cmp
{
    bool operator ()(int &a,int &b)
    {
        return a>b;  //值小优先级高
    }
};

int main()
{
    priority_queue <int ,vector<int>,cmp> q;
    int x,n,i,ans=0;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&x);
        q.push(x);
    }
    while(q.size()>1)
    {
        int t=q.top();
        q.pop();
        t+=q.top();
        q.pop();
        ans+=t;
        q.push(t);
    }
    printf("%d\n", ans);
    return 0;
}


### 循环队列的定义与基本原理 循环队列是一种特殊的线性数据结构,其操作遵循先进先出 (FIFO) 的原则。它通过将存储空间视为首尾相连的圆圈来提高内存利用率并简化边界条件处理[^1]。 在实现上,通常会设计一个结构体用于管理队列的状态。该结构体会包含以下几个核心成员变量: - `data[]`:动态分配的整型数组,用于实际存储队列中的元素。 - `front` 和 `rear`:分别表示队列头部和尾部的位置索引。 - `length`:当前队列中存在的有效元素数量。 - `MaxLen`:队列的最大容量。 当执行入队 (`enqueue`) 或出队 (`dequeue`) 操作时,需特别注意更新这些指针以及判断队列是否已满或为空的情况。具体而言,可以通过 `(rear + 1) % MaxLen == front` 来检测队列是否满了;而 `front == rear` 则意味着队列为空。 ### C++ 中的简单实现示例 以下是基于上述描述的一个基础版本的循环队列类: ```cpp #include <iostream> using namespace std; struct CircularQueue { int *data; int front, rear; // 头节点和尾节点位置 int length; // 当前队列长度 int MaxLen; // 队列最大长度 CircularQueue(int size){ data = new int[size]; front = rear = 0; length = 0; MaxLen = size; } ~CircularQueue(){ delete [] data; } bool isFull() { return ((rear + 1) % MaxLen == front); } bool isEmpty() { return (front == rear && length == 0); } void enqueue(int value){ if (!isFull()){ data[rear] = value; rear = (rear + 1) % MaxLen; length++; }else{ cout << "yes"; // 输出 yes 表示队列已满 } } int dequeue(){ if(!isEmpty()){ int temp = data[front]; front = (front + 1) % MaxLen; length--; return temp; }else{ throw runtime_error("Queue underflow"); } } }; ``` 此代码片段展示了如何创建、初始化以及操作一个简单的循环队列实例。其中包含了对队列状态的基本判定逻辑,并提供了标准的入队与出队功能。 另外需要注意的是,在某些特殊情况下,题目可能要求非传统的输入形式,比如直接利用字符串作为命令的一部分来进行交互式控制流的设计[^2]。这种需求下就需要额外考虑程序对于不同类型输入源的支持能力及其解析策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值