贪心算法——Fence Repair(POJ 3253)
2017-09-17 12:57
435 查看
题目描述
农夫约翰为了修理栅栏,要将一块很长的木板切割成N块。准备切成的木板长度为L1,L2,L3……LN,未切割前木板的长度恰好为切割后木板长度的总和。每次切断木板时,需要的开销为这块木板的长度。请求出按照目标要求将木板切割完的最小开销是多少?例如长度为21的木板切割成长度为13和8,开销为21;把长度为13的木板切割成5和8,则开销为13,所以将长度为21的木板切割成8,5,8的三块,开销是34.样例输入
N = 3, L = {8,5,8}样例输出
34思路分析
以3
5 8 5为例:
先从无限长的木板上锯下长度为 21 的木板,花费 21
再从长度为21的木板上锯下长度为5的木板,花费5
再从长度为16的木板上锯下长度为8的木板,花费8
总花费 = 21+5+8 =34
更多详细请见《挑战程序设计》p48-49
AC代码
# include <iostream> # include <algorithm> using namespace std; const int MAX_N = 10000; int N, L[MAX_N]; void solve() { long long ans = 0; while (N > 1)//直到计算到木板为一块时为止 { int min1 = 0, min2 = 1; if (L[min1] > L[min2]) swap(min1, min2);//swap 函数的作用是实现两个变量的交换,用到algorithm for (int i = 2; i < N; i++)//从第三块板子开始 { if (L[i] < L[min1])//用第一块和第三块或者后面的板子进行比较,把最小的作为第一块,那么原来的第一块小则变成此时的第二块小 { //此时真正的第一小已经确定 min2 = min1; min1 = i; } else if (L[i] < L[min2])//再把此时的第二块小和第三块以及第三块后面的进行比较,再找一个最小的 { //作为真正的第二小 min2 = i; } } //将两块板进行拼合 int t = L[min1] + L[min2]; ans += t; //整体的思想,采用递归 if (min1 == N - 1) swap(min1, min2); L[min1] = t; L[min2] = L[N - 1]; N--; } printf("%lld\n", ans); } int main() { scanf("%d", &N); for (int i = 0; i < N; i++) { scanf("%d", &L[i]); } solve(); getchar(); getchar(); return 0; }
小结
本题目好像用到了霍夫曼编码hahah,自己看吧。我也不是很懂....相关文章推荐
- 贪心+优先队列(哈夫曼思想)POJ 3253 Fence Repair
- POJ 3253 Fence Repair (哈夫曼)
- poj 3253 Fence Repair
- poj 3253 Fence Repair (哈夫曼)
- poj 3253 Fence Repair
- poj3253 Fence Repair 哈夫曼树
- POJ 3253 Fence Repair(优先队列)
- POJ_3253_Fence Repair
- POJ 3253 Fence Repair
- POJ-3253-Fence Repair
- Poj 3253 - Fence Repair 最小堆
- POJ 3253 Fence Repair (哈夫曼编码基础)
- POJ 3253 Fence Repair
- POJ 3253, Fence Repair
- POJ 3253 Fence Repair 哈夫曼树 优先队列
- POJ 3253 Fence Repair(STL之优先队列)
- 【POJ 3253 Fence Repair】+ 优先队列
- 优先队列——Poj 3253 Fence Repair
- poj 3253 Fence repair
- poj 3253 -- Fence Repair