您的位置:首页 > 其它

poker——合并果子变形

2011-11-01 21:38 141 查看

题目描述

有一棵无穷大的满二叉树,根为start,其余所有点的权值为点到根的距离,如图:



现在你有一些扑克牌,点数从1到13,你要把这些扑克牌全部放到这个树上:

1. 当你把点数为i的扑克牌放在权值为j的点上,那么你会得到i*j的分数。
2. 当你把一个扑克牌放在一个节点上,那么你就不能把别的扑克牌放在这个节点以及这个节点的子树上。

你的目标是最小化你的得分。

输入

输入第一行为一个数字N,表示你有的扑克牌数;
接下来一行N个数字,数字在1到13之间。

输出

一行一个整数,表示你的最小得分

样例输入

3 5 10 13

样例输出

43

提示

数据范围:
30%数据 N<=100
100%数据满足1<=N<=10000

样例说明:



分析就略过了。。

合并果子是经典题目吧。。。。

开始其实没看出来是合并果子。。。。

后来才发现。

我的方法是快排+插排。就这样。

var
i,j:longint;
ans,n,m,k,l,bb:int64;
a:array[0..30000]of int64;
procedure sort(l,r:longint);
var
i,j,x:longint;
begin
i:=l;j:=r;
x:=a[(l+r)>>1];
repeat
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if i<=j then
begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if l<j then sort(l,j);
end;
begin
readln(n);
a[n+1]:=maxlongint*10000000;
for i:=1 to n do read(a[i]);
sort(1,n);
for i:=2 to n-1 do
begin
a[i]:=a[i]+a[i-1];
ans:=ans+a[i];
for j:=i+1 to n+1 do
if (a[i]<a[j])and(a[i]>=a[j-1]) then begin bb:=j-1;break;end;
k:=a[i];
for j:=i to bb-1 do a[j]:=a[j+1];
a[bb]:=k;
end;
writeln(ans+a[n-1]+a
);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: