【NOIP复赛模拟题(一)】【第2题】破译密码
Time Limit:1000MS
Total Submit:9 Accepted:5
Description
破译密码(password.pas/c/cpp)
【题目描述】
Feli得到总部发来的消息,我军特种部队已经截获敌人的一个密码本,但是这个密码本本身是由密码写成的。为了给敌人造成沉重的打击,Feli必须尽快破译密码。
经过一天一夜的探索,Feli发现日军密码本实际上记载着一个数列,而最终密码由这个数列经过某种运算得到。运算是这样的:
1.把数列从小到大排序。
2.(分拆)在排好序的数列中,任选一个数,这个数将把原数列分成左右两个数列(选出的数不在新数列中,并且新数列有可能为空)。
3.对每个新数列进行第2步操作,直到最后得到的数列长度都为1,即全部变成单个数。
4.将第3步得到的每个数*(得到它所需的分拆次数+1),累加得到一个和。
5.重复2,3,4操作,直到遍历所有的分拆可能,这时,所得的和当中最小的一个就是日军的最终密码。
6.现在Feli请求你帮助,尽快破译这段密码!
Input
输入文件password.in第一行为N,N≤1000,表示密码本记录的数列的长度。
下一行共有N个数,即日军密码本记载的数列。
Output
输出文件password.out为一个整数,即日军最终密码。
Sample Input
3 1 3 2
Sample Output
10
Hint
【样例说明】
1.数列排序得 1 2 3
2.选出一个数 2
3.分拆得
2
/ \
1 3
此时新的数列(1,3)长度都已经是1,因此无须再分拆
4.求和,2*1+1*2+3*2=10(2在原数列,故乘1;1和3都经过一次分拆,故乘2)
2.选出一个数 1
3.分拆得
1
\
2 3
2 3中选一个数 2,分拆得
1
\
2
\
3
4.求和,1*1+2*2+3*3=14
……
……
所有和当中最小的是10,故输出10
Source
开始还以为是树形动归,所以就直接搜了。
其实就是个区间动归。其中要用到“四边形不等式”。
具体我也不懂。。
var
procedure init;
var
begin
end;
procedure main;
var
begin
end;
begin
end.