Divide

来源:互联网 发布:远程木马监控软件 编辑:程序博客网 时间:2024/06/10 01:59

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.

原创粉丝点击