Fence Repair(POJ 3253)

农夫约翰为了修理栅栏,要将一块很长的木板切割成 N 块,准备切成的木板长度为 Ln ,未切割前木板的长度恰好为切割后木板长度的总和。每次切断木板时,需要的开销为这块木板的长度。例如长度为21的木板要切成长度为 5、8、8 的三块木板,长 21 的木板切成长度为 13 和 8 的木板时 开销为 21 。再将长度为13的板切成长度为 5 和 8 的板时,开销为 13 。于是合计开销为 34 。 请求出按照目标要求将木板切割完的最小开销是多少。

题目中 1 <= N <= 20000 , 0 <= Li <= 50000

输入:第一行是将木板切割成的块数 N ,第二行有 N 个数,分别为第 Li 块木板的长度。

输出:k,木板切割完的最小开销。

sample input:

3

8 5 8

sample output:

34
 

贪心,其实就算霍夫曼编码的思想,开销越大的越先切

34 = (5+8) *2  + 8 = 34

# include <bits\stdc++.h>
using namespace std;

typedef long long ll;
const int MAX_N = 20010;

int N, L[MAX_N];

void solve()
{
    ll ans = 0;

    // 直到计算到模板1块为止
    while (N > 1)
    {
        // 求出最短的板和次短的板
        int mii1 = 0, mii2 = 1;
        if(L[mii1] > L[mii2])
            swap(mii1, mii2);

        for (int i = 2; i < N; i++)
        {
            if(L[i] < L[mii1])
            {
                mii2 = mii1;
                mii1 = i;
            }
            else if(L[i] < L[mii2])
            {
                mii2 = i;
            }
        }

        // 将两块木板合并
        int t = L[mii1] + L[mii2];
        ans += t;

        if(mii1 == N - 1)
            swap(mii1, mii2);
        L[mii1] = t;
        L[mii2] = L[N - 1];
        N--;
    }

    cout << ans;
}

还可以有更好的方法解决

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值