Divide
[题目描述]
GG有n份工作要完成,每一份工作有一个类型系数Ak。由于工作数目太多了,GG光靠自己的能力是无法完成的,所以他打算雇佣很多工人来帮他。工人是非常精明的,他们要求按照工作数目收费,如果分派给他的工作数目小于k,他们将不愿意接受。工人完成一份工作的收费是C。但是,GG也是很精明的老板,考虑到有些工作之间很类似,完成了一份工作之后可以很轻松的完成下一份工作,所以他提出了这样的要求,假设工人接受的工作的类型系数是{B1, B2, B3 … Bp},他能够得到的报酬将是C + (maxB – minB)2。
作为GG的助理,现在你有责任告诉他,为了完成这些工作,他至少要支付多少钱给工人(不算你的工资)?
[输入文件]
第一行三个正整数n、k、C(1 <= k <= n <= 106,0 < C <= 109),意义如题所述;
第二行n个正整数描述n份工作的类型系数(0 < A <= 109)。
[输出文件]
一个整数表示GG最少需要支付的工资(保证答案不大于1017)。
[样例输入]
2 1 1
2 4
[样例输出]
2
[样例说明]
如果分给一个工人做,收费为1 + (4 – 2)2 = 5;
如果分给两个工人作,收费为1 + 1 = 2;
所以最小收费为2。
[数据约定]
对于50分的测试数据中保证有N <= 1000
对于80分的测试数据中保证有N <= 100000
======================================
60分算法..
===================
var
n,k,c:longint;
a:array[1..1000000]of int64;
f:array[0..1000000]of int64;
procedure init;
begin
assign(input,'divide.in');
assign(output,'divide.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function min(a,b:int64):int64;
begin
if a<b then exit(a);
exit(b);
end;
procedure qsort(s,t:longint);
var
i,j:longint;
x:longint;
tem:longint;
begin
x:=a[(s+t) shr 1];
i:=s; j:=t;
repeat
while x<a[j] do dec(j);
while a[i]<x do inc(i);
if i<=j then
begin
tem:=a[i];
a[i]:=a[j];
a[j]:=tem;
inc(i); dec(j);
end;
until i>j;
if i<t then qsort(i,t);
if s<j then qsort(s,j);
end;
procedure main;
var
i,j:longint;
begin
readln(n,k,c);
fillchar(f,sizeof(f),$7f);
for i:=1 to n do read(a[i]);
qsort(1,n);
{for i:=1 to n do
write(a[i],' '); }
f[0]:=0;
for i:=k to n do
for j:=i-k downto 0 do
begin
f[i]:=min(f[i],f[j]+sqr(a[i]-a[j+1])+c);
end;
writeln(f[n]);
end;
begin
init;
main;
terminate;
end.