您的位置:首页 > Web前端

贪心算法——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,自己看吧。我也不是很懂....
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: