poj-3253
来源:互联网 发布:乘联会新能源销量数据 编辑:程序博客网 时间:2024/06/08 10:40
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
priority_queue<long long, vector<long long>, greater<long long> > intQueue;
const int QUEUE_SIZE = 20010;
template <typename T>
struct LessComparator {
char operator()(const T & p1, const T & p2) {
return p1 < p2;
}
};
template <typename T, class C>
class my_priroity_queue {
private:
T mArray[QUEUE_SIZE];
int mQueueSize;
C mComparator;
void adjust_heap_node_up(int NodePos) {
int parentPos = NodePos;
int leftChildPos = 2*NodePos + 1;
int rightChildPos = 2*NodePos + 2;
// cout<<"p "<<parentPos<<" l "<<leftChildPos<<" r "<<rightChildPos<<" "<<mArray[leftChildPos]<<" "<<mArray[parentPos]<<" "<<mArray[rightChildPos]<<endl;
if (rightChildPos + 1 <= mQueueSize) { // 2
int min = mComparator(mArray[parentPos], mArray[leftChildPos]) ? parentPos : leftChildPos;
min = mComparator(mArray[min], mArray[rightChildPos]) ? min : rightChildPos;
if (min == parentPos) {
// cout<<"2 == "<<parentPos<<" "<<mArray[leftChildPos]<<" "<<mArray[parentPos]<<" "<<mArray[rightChildPos]<<endl;
return;
} else {
T tmp = mArray[min];
mArray[min] = mArray[parentPos];
mArray[parentPos] = tmp;
if (!parentPos) {
return;
}
adjust_heap_node_up((parentPos-1)/2);
}
} else if (leftChildPos + 1 <= mQueueSize){ // 1
int min = mComparator(mArray[parentPos], mArray[leftChildPos]) ? parentPos : leftChildPos;
if (min == parentPos) {
// cout<<"1 == "<<parentPos<<endl;
return;
} else {
T tmp = mArray[min];
mArray[min] = mArray[parentPos];
mArray[parentPos] = tmp;
if (!parentPos) {
return;
}
adjust_heap_node_up((parentPos-1)/2);
}
} else {
// cout<<"3 return "<<NodePos<<endl;
return;
}
}
void adjust_heap_node_down(int NodePos) {
int parentPos = NodePos;
int leftChildPos = 2*NodePos + 1;
int rightChildPos = 2*NodePos + 2;
if (rightChildPos + 1 <= mQueueSize) { // 2
int min = mComparator(mArray[parentPos], mArray[leftChildPos]) ? parentPos : leftChildPos;
min = mComparator(mArray[min], mArray[rightChildPos]) ? min : rightChildPos;
if (min == parentPos) {
return;
} else {
T tmp = mArray[min];
mArray[min] = mArray[parentPos];
mArray[parentPos] = tmp;
if (min*2 + 2 + 1 > mQueueSize) {
return;
}
adjust_heap_node_down(min);
}
} else if (leftChildPos + 1 <= mQueueSize){ // 1
int min = mComparator(mArray[parentPos], mArray[leftChildPos]) ? parentPos : leftChildPos;
if (min == parentPos) {
return;
} else {
T tmp = mArray[min];
mArray[min] = mArray[parentPos];
mArray[parentPos] = tmp;
if (min*2 + 1 + 1 > mQueueSize) {
return;
}
adjust_heap_node_down(min);
}
} else {
// cout<<"3 return "<<NodePos<<endl;
return;
}
}
void matain_heap_after_insert() {
int beginNode = (mQueueSize-2)/2;
adjust_heap_node_up(beginNode);
}
void matain_heap_after_pop() {
int beginNode = 0;
adjust_heap_node_down(beginNode);
}
public:
my_priroity_queue(C cmp): mQueueSize(0), mComparator(cmp) {
memset(mArray, 0, sizeof(mArray));
}
T top() {
return mArray[0];
}
void push(T val) {
mArray[mQueueSize++] = val;
matain_heap_after_insert();
// cout<<"size "<<mQueueSize<<endl;
// for (int i = 0; i < mQueueSize; i++) {
// cout<<mArray[i]<<endl;
// }
}
void pop() {
if (mQueueSize) {
mArray[0] = mArray[--mQueueSize];
if (mQueueSize) {
matain_heap_after_pop();
}
}
}
int size() {
return mQueueSize;
}
};
struct LessComparator<long long> cmp;
my_priroity_queue<long long, struct LessComparator<long long> > my_queue(cmp);
void getMinCost() {
long long totalCost = 0;
while(my_queue.size() > 1) {
long long costThisTime = my_queue.top();
// cout<<my_queue.top()<<endl;
my_queue.pop();
costThisTime += my_queue.top();
// cout<<my_queue.top()<<endl;
my_queue.pop();
my_queue.push(costThisTime);
totalCost += costThisTime;
}
//totalCost += intQueue.top();
my_queue.pop();
cout<<totalCost<<endl;
}
int TEST() {
cout<<"TEST"<<endl;
my_queue.push(537);
my_queue.push(4189);
my_queue.push(652);
my_queue.push(3127);
// my_queue.pop();
// cout<<"RES"<<endl;
// while(my_queue.size()) {
// cout<<my_queue.top()<<endl;
// my_queue.pop();
// }
my_queue.push(4673);
my_queue.push(1364);
my_queue.push(40);
// my_queue.pop();
// cout<<"RES"<<endl;
// while(my_queue.size()) {
// cout<<my_queue.top()<<endl;
// my_queue.pop();
// }
my_queue.push(854);
my_queue.push(2326);
my_queue.push(1016);
my_queue.push(1307);
my_queue.push(3372);
my_queue.push(4663);
my_queue.push(2164);
my_queue.push(2833);
my_queue.push(3037);
my_queue.push(4758);
my_queue.push(4757);
my_queue.push(4633);
my_queue.push(2942);
cout<<"RES"<<endl;
my_queue.pop();
my_queue.pop();
my_queue.push(577);
while(my_queue.size()) {
cout<<my_queue.top()<<endl;
my_queue.pop();
}
}
int main() {
// TEST();
while(1) {
int num = 0;
cin>>num;
if (cin.eof()) {
return 0;
}
// intQueue.clear();
for (int i = 0; i < num; i++) {
long long tmp;
cin>>tmp;
my_queue.push(tmp);
}
getMinCost();
// while(intQueue.size()) {
// cout<<intQueue.top()<<endl;
// intQueue.pop();
// }
}
}
C++ 94ms(STL queue)
G++ 157MS(自己写的优先级queue)
用了哈夫曼树的原理,以及STL的 priority_queue.
这道题让我重新认识了哈夫曼树,以前对哈夫曼树的认识被局限在那个求编码的例子中。
遇到这道题根本没想到能用哈夫曼,一开始想用动态规划来着,后来发现虽然DP理论上可以用,但是结合这道题是基本不行的,因为数位太多了(20000)
后来看到有说可以用哈夫曼,但是不理解为什么能够向哈夫曼树转化,后来仔细读了算导的哈夫曼树:
哈夫曼树能得到这样的最小值,对于一系列的值Array[i]:
D(i)*Array(i)的全部和最小。 其中 D(i)是该值(叶子节点)在哈夫曼树中的深度,Array[i]是数组的第i个值。
那么对于本题来说,按照锯木头的顺序来构造一颗二叉树,那么总和花费也可以表示为:
D(i)*L(i)的总和, D(i) 是第i个plank在树中的深度,而L(i)则是plank i的长度,为什么总花费能够用这样表示,
是因为,对于某个plank来说,从开始切割到最后终于将plank i切割出去,因为plank i带来的cost一共就是D(i)*L(i),
举个简单例子, 5个plank, L: 1 2 3 4 5
这样切割的顺序:
12345
12 345
1 2 3 45
4 5
可以看到,切割4/5的总代价就是其本身长度乘以其深度(这是因为除非plank被切割出去,否则必然会参与下一次分割,那么其长度就会附加到下一次的切割花费中)。
也可以称此题为求该树全部父节点和最小的问题(因为每个父节点必是一次切割,代价则是两个子节点的代价和)
这样,就能转化为哈夫曼树的问题了。
要记住这个经典的哈夫曼树运用模式。
还有需要注意的是,最后的cost要用long long
自己写优先级queue的时候,在求父子节点index的表示时,因为数组index是从0开始的,
因此对于父节点index = p,子节点inex: left = 2*p + 1 right = 2*right + 2
而对于子节点index = i, 其父节点应该为(i-2)/2。
队列对于解某些算法题确实是好东西,BFS也经常用到.
- POJ 3253
- poj 3253
- poj 3253
- poj 3253
- poj----3253
- poj.3253
- poj 3253
- POJ 3253
- poj 3253
- poj-3253
- POJ-3253
- POJ 3253
- poj 3253
- poj-3253
- poj-3253
- POJ 3253
- POJ 3253
- POJ 3253
- boost 系列四 Array和FOREACH
- centos 按装好apache服务, 页面无法访问解决办法 80端口没开
- MySQL 5.1 windows安装 与 简易教程
- 【DP】 TJU 4087
- imx536开发板启动打印信息一览
- poj-3253
- 详解UML中的6大关系(关联、依赖、聚合、组合、泛化、实现)
- [leetcode] Largest Rectangle in Histogram
- ASP.NET 模式窗口(子父窗口之间的传值)
- sql 长度不够时补全函数
- [leetcode] Maximal Rectangle
- Eclipse快捷键汇总
- 【android】十二个移动App云测试服务盘点
- HTTP协议中常见请求方法以及一些常见错误代码