FZU - 2219 StarCraft
2016-04-04 17:54
274 查看
1.题面
http://acm.fzu.edu.cn/problem.php?pid=22192.题意
你有m个工人,要造n个建筑,每个工人只能建造一个建筑,每个建筑只能被一个工人造。但是你有一项技能,你可以选择一个工人,把他变成一个蛋,这样k个时间单位后,这个蛋就会孵化出两个工人。现在给出建造第i栋建筑需要的时间t[i],求建造完这所有n栋建筑需要的时间。
3.思路
这道题中每一种建造方案都可以用图来表示,图中有m棵二叉树,表示m个初始工人,每一次分叉都是使用魔法将一个工人变成两个工人,因为每次需要k单位的时间,所以我们将每条边的权值设置为k,分叉节点的权值设为0。然后如果这个工人不再进行分裂,而是去做建造第i个建筑,它的下方就直接接一个权值为t[i]的节点。为了说明的方便,我们引入一个虚的根节点,从根节点往这m棵树的树根每个都引一条权值为0的边。
那么我们的问题就变成了,找出一种方案,使所有叶子节点到虚的根节点中的权值和的最大值最小。
在这样一棵树中,所有的叶子节点都代表一个建设建筑物的操作。
可以证明,如果一个(距离根节点较远的叶子节点)的权值大于(一个距离根节点距离较小的节点),我们交换这两个节点之后结果必然不会更坏,而且有可能会更好。
根据以上性质,我们可以推测出,在一棵最优的树中权值最小的两个节点,距离根节点的距离也必然是最大的。至于为什么是两个呢,因为权值最小的节点必然有兄弟啊。
这个样子,我们就找到了最底端的两个节点,同时也解决了这个问题。因为在找到了最底端的两个节点之后,我们可以将它们删除,同时将它们的父亲节点的权值设置为max(LeftChild,RightChild)+k。我们的问题就变成了如何是剩下的节点最优,这是一个已经解决的问题。
4.代码
/***************************************************************** > File Name: tmp.cpp > Author: Uncle_Sugar > Mail: uncle_sugar@qq.com > Created Time: 2016年04月01日 星期五 20时31分43秒 *****************************************************************/ # include <cstdio> # include <cstring> # include <cmath> # include <cstdlib> # include <climits> # include <iostream> # include <iomanip> # include <set> # include <map> # include <vector> # include <stack> # include <queue> # include <algorithm> using namespace std; const int debug = 1; const int size = 5000 + 10; const int INF = INT_MAX>>1; typedef long long ll; int main() { std::ios::sync_with_stdio(false);cin.tie(0); int i,j; int T; cin >> T; priority_queue<int,vector<int>,greater<int> > pri_que; while (T--){ while (!pri_que.empty()) pri_que.pop(); int n,m,k,tmp; cin >> n >> m >> k; for (i=0;i<n;i++){ cin >> tmp; pri_que.push(tmp); } while (pri_que.size()>m){ pri_que.pop(); tmp = pri_que.top(); pri_que.pop(); pri_que.push(tmp+k); } while (pri_que.size()>1) pri_que.pop(); cout << pri_que.top() << '\n'; } return 0; }
相关文章推荐
- 基于NodeJS的秘室聊天室
- RNN循环神经网络Recurrent Networks
- 【转载】C#进程间通讯
- JAVA常用的垃圾回收器
- oracle中建同名
- Twitter Heron:流式计算Storm的升级版
- poi之Excel常用操作
- java;继承,多个类main函数用法
- leetcode 27 remove element
- 循环神经网络教程4-用Python和Theano实现GRU/LSTM RNN, Part 4 – Implementing a GRU/LSTM RNN with Python and Theano
- 程序的灵魂 ---算法
- New Moto X 2014 全版本RSD&Fastboot刷官方底包教程
- 一站式学习Wireshark(四):网络性能排查之TCP重传与重复ACK
- 循环神经网络教程3-BP算法和梯度消失问题, Part 3 – Backpropagation Through Time and Vanishing Gradients
- struts2笔记04-XxxAware接口
- Jquery操作XML
- 《Swift入门》Ubuntu 14 server安装Swift运行环境
- HIbernate继承映射策略
- [android] 手机卫士欢迎页检测更新
- hdu 3966( 树链剖分+点权更新)