POJ-3253 Fence Repair

农夫约翰想修理牧场周围的一小段围栏。他测量围栏并认定他需要Ñ(1≤ Ñ ≤20000)厚木板,每一个都具有一些整数长度大号(1≤ 大号 ≤50000)单元。然后,他购买一块长板足够长,以便看到N块板(即,其长度是长度i的总和)。FJ忽略了“切口”,锯齿切割时锯屑的额外长度; 你也应该忽略它。

FJ悲伤地意识到,他没有一把砍伐木头的锯子,所以他用这张长板子将农民交给了Farmer Don's Farm,并礼貌地问他是否可以借用一把锯子。

一个衣柜资本家农夫唐(Donmer Don)并不是向FJ借一把锯子,而是向该农民约翰收取木板上N-1个切口的费用。砍一块木头的费用与其长度完全相等。切割长度为21的木板需要21美分。

农夫唐然后让农夫约翰决定顺序和地点切割木板。帮助Farmer John确定他可以用来创建N木板的最小金额FJ知道他可以用各种不同的顺序切割板子,这将导致不同的收费,因为所产生的中间板条具有不同的长度。

输入
第1行:一个整数  N ,木板数量 
第2行..  N  + 1:每行包含一个描述所需木板长度的整数
产量
第1行:一个整数:他必须花费最少的金钱来制作  N  -1个剪辑
示例输入
3
8
5
8
示例输出
34
暗示
他希望将长度为21的棋盘切成长度为8,5和8的棋子。
原来棋盘上的棋子为 8 + 5 + 8 = 21。第一次切割将花费21美元,并且应该用于将板切割成13和8片。第二次切割将花费13,并且应该用于将13切割成8和5.这将花费21 + 13 = 34 。如果21被切割成16和5,则第二次切割将花费16次,总共37次(大于34次)。
思路分析:

        这道题是我初试优先队列的题,所以一定要拿个小本子记下来。

        这道题的思路其实挺简单的,就是每次找两个最小的数求和,并将他们两数的和弹入队列即可,直到队列中只剩下最后一个元素即可。

此处主要代码为:

while(q.size()!=1)

        {

            ll a=q.top();

            q.pop();

            ll b=q.top();

            b=q.top();

            q.pop();

            ll c=a+b;

            ans+=c;

            q.push(c);

        }

文末最后提一下优先队列:

priority_queue<long long ,vector<long long> ,greater<long long> >;这个是单增的队列

priority_queue<long long ,vector<long long> ,less<long long> >;这个是单减的队列

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<limits>
#include<queue>
using namespace std;
typedef long long ll;
int N;
ll l[20005];
ll ans;
priority_queue<ll ,vector<ll>,greater<ll> >q;
int main()
{
    while(scanf("%d%*c",&N)!=EOF)
    {
        ans=0;
        while(!q.empty())
        {
            q.pop();
        }
        for(int i=0;i<N;i++)
        {
            scanf("%lld%*c",&l[i]);
            q.push(l[i]);
        }
        while(q.size()!=1)
        {
            ll a=q.top();
            q.pop();
            ll b=q.top();
            b=q.top();
            q.pop();
            ll c=a+b;
            ans+=c;
            q.push(c);
        }
        printf("%lld\n",ans);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值