[POJ] 3253柵の修理
元のタイトル
柵の修理
制限時間:2000MS
メモリ制限:65536K
説明
農夫ジョンは牧草地の周りの短い長さの柵を修理したいと思っています。彼は柵を測定し、それぞれが整数の長さのLi(1≤Li≤50,000)単位を持つN(1≤N≤20,000)の木の板が必要であることを発見しました。次に、彼はN枚の板をのこぎりで切るのに十分な長さの1枚のロングボードを購入します(つまり、その長さは長さLiの合計です)。FJは、おがくずが行われたときにおがくずに失われる余分な長さである「切り口」を無視しています。あなたもそれを無視するべきです。
FJは悲しいことに、自分が木を切るためののこぎりを持っていないことに気付いたので、この長いボードを持ってファーマードンズファームに行き、のこぎりを借りてもいいかと丁寧に尋ねました。
クローゼットの資本家であるファーマードンは、FJにのこぎりを貸しませんが、代わりに、プランクのN-1カットごとにファーマージョンに請求することを提案します。木片を切るための料金は、その長さとまったく同じです。長さ21の厚板を切るには21セントかかります。
次に、ファーマードンはファーマージョンに厚板を切る順序と場所を決定させます。ファーマージョンがN枚の板を作成するために費やすことができる最小金額を決定するのを手伝ってください。FJは、ボードをさまざまな順序でカットできることを知っています。これにより、結果として得られる中間の厚板の長さが異なるため、料金が異なります。
入力
1行目:1つの整数N、厚板の数
2行目…N + 1:各行には、必要な厚板の長さを表す1つの整数が含まれています
出力
1行目:1つの整数:N-1カットを行うために彼が費やす必要のある最小金額
サンプル入力
3
8
5
8
サンプル出力
34
ヒント
彼は、長さ21のボードを長さ8、5、および8
の断片にカットしたいと考えています。元のボードのサイズは8 + 5 + 8 = 21です。最初のカットのコストは21で、ボードを13と8の小片にカットするために使用する必要があります。2番目のカットのコストは13で、13を8と5にカットするために使用する必要があります。これは21 + 13 = 34のコストになります。 。代わりに21が16と5にカットされた場合、2番目のカットは合計37(34以上)で16のコストがかかります。
翻訳
柵の修理
制限時間:2000MS
メモリ制限:65536K
説明
農夫ジョンは牧場の周りの柵の小さな部分を修理したいと思っています。彼は柵を測定し、それぞれが整数の長さの大きいI(1≤大きいI≤50000)単位を持つÑ(1≤Ñ≤20000)の厚い厚板が必要であることを発見しました。次に、彼はN枚のボードにカットするのに十分な長さのロングボードを1枚購入しました(つまり、その長さはLiの長さの合計です)。FJは、おがくずが原因で失われる余分な長さである「のこぎりギャップ」を無視します。これも無視する必要があります。
FJは残念ながら、木を切るためののこぎりがないことに気づき、長い板でファーマー・ドンズ・ファームにそれをはめ込み、のこぎりを借りてもいいかと丁寧に尋ねました。
クローゼットの資本家であるファーマードンは、FJソーを貸しませんが、プランクのN-1カットをファーマージョンに請求するイニシアチブを取ります。木片を切るコストは、その長さに正確に等しくなります。長さ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のサイズにカットするために使用する必要があります。2番目のカットのコストは13で、13を8と5のサイズにカットするために使用する必要があります。これには21+ 13 = 34の費用がかかります。21から16にカットし、5をカットした場合、2番目のカットは16で、合計37(34以上)になります。
アイデア
[SSL] 1040 2004 Divisional League Improvement Group 2 MergerFruitに類似しています。
ヒープを使用します。
最初に山を作ります。
ヒープソート
毎回ヒープの上位2つを取り出し、合計して、ヒープに挿入します。
コード
#include<iostream>
#include<cstdio>
using namespace std;
const long long maxlenth=20010;
class heap
{
private:
long long h[maxlenth],len=0;
void up(long long x);//上移操作,把h[x]上移的合适位置
void down(long long x);//下移操作,把h[x]下移的合适位置
bool cmp(long long x,long long y);
public:
void swap(long long &t1,long long &t2);//交换两数
void build(long long x);//建堆
void sort();//堆排序
void del(long long x);//删除操作,删除h[x]
void push(long long x);//插入操作,把x加入堆的合适位置
long long top();//返回堆顶的值
void pop();//删除堆顶
bool empty();//判断堆是否空
long long size();//返回堆的长度
};
bool heap::cmp(long long x,long long y)//若x比y优,return 1,若y比x优,return 0
{
return h[x]<h[y];
}
void heap::swap(long long &t1,long long &t2)//交换两数
{
long long t=t1;
t1=t2,t2=t;
return;
}
void heap::up(long long x)//上移操作,把h[x]上移的合适位置
{
if(x>len)return;
for(;x>1;x>>=1)
if(cmp(x,x>>1)) swap(h[x],h[x>>1]);
else return;
return;
}
void heap::down(long long x)//下移操作,把h[x]下移的合适位置
{
if(x<1)return;
for(x<<=1;x<=len;x<<=1)
{
x+=(x+1<=len&&cmp(x+1,x));
if(cmp(x,x>>1)) swap(h[x>>1],h[x]);
else return;
}
return;
}
void heap::push(long long x)//插入操作,把x加入堆的合适位置
{
h[++len]=x;
up(len);
return;
}
void heap::del(long long x)//删除操作,删除h[x]
{
if(x<1||x>len)return;
if(cmp(len,x)) h[x]=h[len--],up(x);
else h[x]=h[len--],down(x);
return;
}
void heap::sort()//堆排序
{
for(;len;h[1]=h[len--],down(1))
{
//a[i]=h[1];
printf("%lld",h[1]);
}
return;
}
void heap::build(long long x)//建堆
{
long long i;
for(len=0,i=1;i<=x;i++)
{
//h[++len]=a[i];
scanf("%lld",&h[++len]);
up(len);
}
return;
}
long long heap::top()//返回堆顶的值
{
if(empty())//堆为空
return 0;//崩溃
return h[1];
}
void heap::pop()//删除堆顶
{
del(1);
return;
}
bool heap::empty()//判断堆是否空
{
return !len;
}
long long heap::size()//返回堆的长度
{
return len;
}
int main()
{
heap h;
long long n,ans=0,tem;
scanf("%lld",&n);
for(h.build(n);h.size()>1;h.push(tem))
{
tem=h.top();
h.pop();
tem+=h.top();
h.pop();
ans+=tem;
}
printf("%lld",ans);
return 0;
}