POJ 3253 贪心+优先队列

农夫约翰想修理牧场周围的一小段篱笆。他量了量篱笆,发现自己需要N(1≤)N(≤20,000)木板,每个木板都有一定的整数长度Li(1≤)Li≤50,000)单位。然后,他买了一张长板,只要够长,就能把它锯进去。N木板(即,其长度为长度之和)Li)。FJ忽略了“切口”,这是锯屑造成的额外长度损失,你也应该忽略它。

FJ悲伤地意识到他没有一把锯子可以用来砍柴,于是他带着这块长板来到农夫堂农场,礼貌地问他是否可以借一把锯子。

农民唐,一个壁橱资本家,不借给FJ一把锯子,而是主动向农民约翰收取每一笔钱。N-木板上有一个切口。切割一片木头的药量与其长度完全相等。切一块长21的木板要花21美分。

农民唐然后让农民约翰决定的顺序和位置,以削减木板。帮助农民约翰确定他可以花多少钱来创建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)。

代码一:

#include<cstdio>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<iostream>
#include<set>
#define LL long long
using namespace std;
int main(){
    priority_queue<int,vector<int>,greater<int> >q;
    int n,a;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a);
        q.push(a);
    }
    LL x,y;
    LL s=0;
    for(int i=n;i>1;i--){
        x=q.top();
        q.pop();
        y=q.top();
        q.pop();
        x+=y;
        s+=x;
        q.push(x);
    }
    printf("%lld\n",s);
    return 0;
}

代码二:

#include<cstdio>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<iostream>
#include<set>
#define LL long long
using namespace std;
struct A{
    LL a;
    bool operator<(const A n1)const{
        return n1.a<a;
    }
};
int main(){
    priority_queue<A>q;
    int n,a;
    A t;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a);
        t.a=a;
        q.push(t);
    }
    A x,y;
    LL s=0;
    for(int i=n;i>1;i--){
        x=q.top();
        q.pop();
        y=q.top();
        q.pop();
        x.a+=y.a;
        s+=x.a;
        q.push(x);
    }
    printf("%lld\n",s);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值