• SOJ4459 skysky's game(贪心+优先队列)


    天天最近迷上了天天爱消除游戏,现在他觉得这个游戏已经没有意思了。所以他发明一个新的消除游戏。有n堆糖果,每一个糖果有一个重量w,天天每次都选择两个糖果合并为一个糖果,新的糖果的重量等于这两个糖果的重量之和,并且他将获得等价于这两个糖果重量的值。直到只剩下一个糖果为止。现在天天想知道他最后最少获得的值是多少?

    Input

    第一行包含一个整数t(t<=10),代表组数 对于每一组数据,首先是一个整数n(n<=100000),代表有n堆糖果。接下来有n个数wi(0<=wi<=100000)代表每个糖果的重量。

    Output

    对于每一组数据,输出一个整数,代表天天最少获得的重量的值。

    Sample Input

    1
    3
    1 2 3
    
    

    Sample Output

    9


    思路:本题核心是贪心,和哈弗曼树的构造原理相同。每次选取最小的两个数值进行相加,将和加到ans中保存,之后将两者相加的值放回去。不过本题需要注意的是由于返回后需要排序,如果每一次都进行sort()会超时,据shuaishuai说本题使用归并排序好像是可行的,但是没有尝试不清楚。个人推荐用数据结构来进行维护,我是用的优先队列(《挑战程序设计竞赛》P71),保证了时间。

    AC代码:
    #include <stdio.h>
    #include <queue>
    #include <iostream>
    using namespace std;
    
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            priority_queue<int,vector<int> , greater<int> > que;
            for(int i=0;i<n;i++){
                int temp;
                scanf("%d",&temp);
                que.push(temp);
            }
            long long ans=0;
            while(que.size()!=1){
                int a=que.top();que.pop();
                int b=que.top();que.pop();
                ans+=a+b;
                que.push(a+b);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    } 

    ps:这个题目由于数据规模较大所以只能使用贪心求解,当数据范围较小时也可以把这个题目理解为区间DP,使用尺取法求解

  • 相关阅读:
    msbuild.exe保持打开状态,锁定文件
    angular中使用echarts并实现数据更新
    浅谈flexible.js移动端自适应方案
    centos7 安装
    尚硅谷Java基础篇(717集)
    auto 和 decltype
    一个简单的 socket 网络编程
    项目搭建过程中初始化mysql常遇到的问题总结
    超微服务器内存不在位
    UEFI模式下修改RAID组cache方法
  • 原文地址:https://www.cnblogs.com/87hbteo/p/7284361.html
Copyright © 2020-2023  润新知