poker——合并果子变形

题目描述

有一棵无穷大的满二叉树,根为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

样例说明:

分析就略过了。。

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

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

后来才发现。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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[n]);
end.

posted on   codeway3  阅读(410)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?

导航

< 2011年11月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10

统计

点击右上角即可分享
微信分享提示