POJ 3253(Fence Repair)

题目链接:https://vjudge.net/problem/POJ-3253
意思:一道贪心的题目,要求将木块切成指定的长度,每切一次的开销是切之前的总长度,问最小开销。
思考:很自然的想到反向还原,从最终结果还原为完整的一根木块,每次还原的代价就是拼接后的总长度。也就是说每次拼接后,后面再拼接都需要计算当前木块的长度。举个例子,原始有长度为1 3的木块,那么如果第一次拼接他们,后面每次拼接都需要加一次1和3,。而拼接的总次数是一定的,那么很自然的想到从最小的两个开始拼接,接好后算作新的一根,再取最小的两个拼接,一直直到最后拼成完整的一根,这种贪心的正确性是显而易见的。需要注意的是,如果结果本身就是一整根,需要的代价就是这根的长度而不是0,需要特别拿出来。
由于最大的木块数目是50000,o(n2)的算法大概率会TL,如果采取优先级队列,每次取出来两根,再拼接放进去,复杂度是o(nlogn),可以满足要求。

代码:
#include
#include
#include
using namespace std;

struct cmp{ //重新定义排序方法
bool operator()(int x,int y){
return x>y;
}
};

priority_queue ,cmp> a; //队列储存木块长度
int main(){
int n;
cin>>n;
int now;
while(n--){
cin>>now;
a.push(now);
}
long long int result = 0;

if(a.size()==1){ //等于1的情况需要单独讨论
    result+=a.top();
}
else{
while(a.size()>1){
    int now1 = a.top();
    a.pop();
    int now2 = a.top();
    a.pop();
    a.push(now1+now2);
    result+=(now1+now2);
}
}

cout<

return 0;
}

你可能感兴趣的:(POJ 3253(Fence Repair))