牧場の修理
農夫は牧場の柵の一部を修理したいと思っていました。柵を測定したところ、N枚の木が必要であることがわかりました。各木片の長さはLi単位の整数であるため、非常に長い木を購入しました。 N個に切ることができる木の長さはLiの合計です。
しかし、農民は自分でのこぎりを持っておらず、誰かを使って木を見た報酬は、木片の長さに比例します。簡単にするために、報酬を製材の長さに等しく設定します。たとえば、長さ20の木材を長さ8、7、5の3つのセグメントに鋸で挽く場合、最初の木材の鋸引きは20、木材の鋸引きは12と8、2回目の鋸引きは12です。長さは12です。7と5に鋸で挽かれた木材の合計コストは32です。木材を初めて15と5に鋸で挽く場合、2回目の鋸引きの費用は15で、合計費用は35(32以上)になります。
農民が木材をN個に鋸で切る最小コストを計算するのに役立つプログラムを書いてください。
入力フォーマット:
入力は最初に正の整数N(≤10^ 4)を与えます。これは、木材がN個に切断されることを意味します。2行目は、N個の正の整数(≤50)を示し、各木材の長さを示します。
出力フォーマット:
整数を出力します。これは、木材をN個に切断するための最小コストです。
入力サンプル:
8
4 5 1 2 1 3 1 1
サンプル出力:
49
題名:
考え方はとてもシンプルです。長い木をn個に分割します。現在の木材を切断する場合は、切断料金を支払う必要があります。切断料金は現在の木材の長さと同じです。終了します。あなたが小さな木片をn個手に入れるとき。(長い木はn個の小さな木の合計でなければなりません)そして最後に最小コストを見つけます。
アイデア:
これで、n個の小さな木の長さ(結果)が得られたので、切り方を知りたい場合は、押し戻すしかありません。これが3つのプッシュバック図です。図a、図b、図c
。
コード
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
//这里利用最小堆,即放入队列中的元素会自动从小到大排序。
//为什么要有这个呢
//因为每次都需要找出最小的两个,即需要排序
priority_queue<int,vector<int>,greater<int> > q;
int main()
{
int n;
while(~scanf("%d",&n))
{
int i,x,a,b,s,sum=0;
while(!q.empty())
q.pop();
for(i=0;i<n;i++)
{
scanf("%d",&x);
q.push(x);
}
while(q.size()>=2)
{
a=q.top();
q.pop();
b=q.top();
q.pop();
s=a+b;
q.push(s);
sum+=s;
}
printf("%d\n",sum);
}
return 0;
}