June 11th 模拟赛C T3 Cowski Solution

空降题目处
点我点我点我

Description:

FJ有N(2<=N<=1,500)头牛编号为1到N,FJ新盖了S(N<=S<=1,000,000)个牛棚,编号为1到S,S个牛棚排成一排,相邻牛棚距离为1。
每个牛棚只能住一头牛,每头牛都选择了一个牛棚P_i来休息,当两头牛离得太近时就会变得很暴躁,FJ想移动一些牛到其他牛棚使得他们之间的间距尽可能大,同时FJ又希望这N-1个间距尽可能相似。
帮助FJ用最少的移动距离满足要求。

Input

第1行:两个空格隔开的整数N和S
第2到N+1行:第i+1行包含一个整数P_i

Output

输出一个整数表示最少移动距离。

Solution

典型DP.
使用了神奇的DP式.
D=s1n1
F[i,j] 为到第 i 头牛,有j个间隔为 D+1 的.
则推出方程:
Fi,j=min(Fi1,j,Fi1,j1)+abs(ei(ij1)dj(d+1)1)
取值范围:
2in
0jmin((s1)mod(n1),i1)
初值:
F=maxlongint3
F1,0=e11

Program

uses
    math;

var
    d,n,s,i,j,ans:longint;
    e:array [1..1500] of longint;
    f:array [0..1500,0..1500] of longint;

procedure swap(var x,y:longint);
var 
    t:longint;

begin

    t:=x;
    x:=y;
    y:=t;

end;

procedure Qsort(l,r:longint);
var
    m,i,j:longint;

begin

    i:=l;
    j:=r;
    m:=e[(i+j) shr 1];
    repeat
        while e[i]<m do
            inc(i);
        while m<e[j] do
            dec(j);
        if I<=j then
        begin
            swap(e[i],e[j]);
            inc(i);
            dec(j);
        end;
    until i>j;
    if i<r then
        Qsort(i,r);
    if l<j then
        Qsort(l,j);

end;

begin

    assign(input,'graze2.in');
    assign(output,'graze2.out');
    reset(input);
    rewrite(output);

    readln(n,s);
    d:=(s-1) div (n-1);
    for i:=1 to n do
        readln(e[i]);
    Qsort(1,n);
    for i:=0 to n do    
        for j:=0 to n do
            f[i,j]:=maxlongint div 3;
    f[1,0]:=e[1]-1;
    for i:=2 to n do
        for j:=0 to min(i-1,(s-1) mod (n-1)) do
        begin
            f[i,j]:=min(f[i,j],f[i-1,j]+abs(e[i]-(i-j-1)*d-j*(d+1)-1));
            if j>0 then
                f[i,j]:=min(f[i,j],f[i-1,j-1]+abs(e[i]-(i-j-1)*d-j*(d+1)-1));
        end;
    writeln(f[n,(s-1) mod (n-1)]);

    close(input);
    close(output);

end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值