[2014.3.30]poj3253 Fence Repair 解题报告(C++)
来源:互联网 发布:手机数据迁移软件 编辑:程序博客网 时间:2024/06/05 02:16
【原题】
[Description]
Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needsN (1 ≤N ≤ 20,000) planks of wood, each having some integer lengthLi (1 ≤Li ≤ 50,000) units. He then purchases a single long board just long enough to saw into theN planks (i.e., whose length is the sum of the lengthsLi). FJ is ignoring the "kerf", the extra length lost to sawdust when a sawcut is made; you should ignore it, too.
FJ sadly realizes that he doesn't own a saw with which to cut the wood, so he mosies over to Farmer Don's Farm with this long board and politely asks if he may borrow a saw.
Farmer Don, a closet capitalist, doesn't lend FJ a saw but instead offers to charge Farmer John for each of theN-1 cuts in the plank. The charge to cut a piece of wood is exactly equal to its length. Cutting a plank of length 21 costs 21 cents.
Farmer Don then lets Farmer John decide the order and locations to cut the plank. Help Farmer John determine the minimum amount of money he can spend to create theN planks. FJ knows that he can cut the board in various different orders which will result in different charges since the resulting intermediate planks are of different lengths.
[Input]
Lines 2..N+1: Each line contains a single integer describing the length of a needed plank
[Output]
[Sample Input]
3858
[Sample Output]
34
[Hint]
The original board measures 8+5+8=21. The first cut will cost 21, and should be used to cut the board into pieces measuring 13 and 8. The second cut will cost 13, and should be used to cut the 13 into 8 and 5. This would cost 21+13=34. If the 21 was cut into 16 and 5 instead, the second cut would cost 16 for a total of 37 (which is more than 34).
【思路】例如把长为L=L1+L2+L3的木头切成L1/L2/L3三段
L
/ \
L1+L2 L3
/ \
L1 L2,总共需要花钱L+L1+L2=L1*2+L2*2+L3*1,等于以成品长度为权值的节点构成的二叉树的带权外部路径长度,为了让带权外部路径最小,应该将这些节点构成哈夫曼树,按照哈夫曼树的指示去截木头。
【代码】
#include "stdafx.h"#include "iostream"#include "math.h"using namespace std;//找到长为n的数组a中最小值和次最小值的大小及位置//最小值min1,位置min1_i;次最小值min2,位置min2_ivoid find_min_i(int a[], int n, int &min1, int &min1_i, int &min2, int &min2_i){min1 = 1000000000;min2 = 1000000000;for(int i = 0; i < n; i++)//扫描整个数组{if(a[i] < min1)//如果小于当前最小值{min2 = min1;min2_i = min1_i;min1 = a[i];min1_i = i;}else if(a[i] < min2)//如果不小于当前最小值但是小于当前次最小值{min2 = a[i];min2_i = i;}}}int main(){int n;cin >> n;int* a = new int[n];for(int i = 0; i < n; i++)cin >> a[i];long long cost = 0;//花费的钱数,一定是long long,int范围不够while(n >= 2)//如果还需要合并{int min1, min1_i, min2, min2_i;find_min_i(a, n, min1, min1_i, min2, min2_i);//找到最小值和次最小值if(min1_i == n-1)//如果最小值在数组最后a[min2_i] = min1 + min2;//则新节点覆盖次最小值else if(min2_i == n-1)//如果次最小值在数组最后a[min1_i] = min1 + min2;//则新节点覆盖最小值else{a[min1_i] = a[n-1];//把数组最后的一个节点搬到前面来a[min2_i] = min1 + min2;//新节点}n--;//数组长度减1cost += (min1 + min2);//又要花钱};cout << cost << endl;delete[] a;}【遗留问题】
求最小值和次最小值改用最小堆来做的话会变快吧?
- [2014.3.30]poj3253 Fence Repair 解题报告(C++)
- POJ3253 Fence Repair
- poj3253 Fence Repair( 贪心 )
- poj3253 Fence Repair
- poj3253 Fence Repair
- poj3253 Fence Repair---赫夫曼树
- poj3253 Fence Repair
- POJ3253 Fence Repair
- POJ3253 Fence Repair
- POJ3253--Fence Repair
- POJ3253 Fence Repair(贪心)
- POJ3253 Fence Repair
- poj3253 Fence Repair
- Poj3253—Fence Repair
- POJ3253-Fence Repair
- POJ3253-Fence Repair
- [POJ3253]-Fence Repair
- POJ3253-Fence Repair
- Google搜索小技巧
- 自建git服务器push时报证书错的解决办法
- php5.4.26 安装出现 error: ‘struct gdIOCtx’ has no member named ‘data’
- ORA-12899: 列 XX 的值太大 (实际值: 521, 最大值:512)
- statfs函数获取大容量磁盘信息速度慢的解决过程
- [2014.3.30]poj3253 Fence Repair 解题报告(C++)
- Python基础教程(第2版)读书笔记
- 网络流 最大流
- Java中接收键盘输入及输出数据的练习
- Catch That Cow(队列)
- stopPropagation, preventDefault 和 return false 的区别
- 无法解析的外部符号 _WinMain@16
- 团队管理--领导力的重要性
- Twitter Storm源代码分析之Topology的执行过程