牛棚(graze2.pas/c/cpp)

(File IO): input:graze2.in output:graze2.out

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希望所有间距与(S-1)DIV(N-1)最多相差1,而且希望这N-1个间距尽可能多的等于(S-1)DIV(N-1)。例如4个牛住8个牛棚,可以有以下方案:1,3,5,8或1,3,6,8,但1,2,4,7或1,2,4,8是不符合要求的。
帮助FJ用最少的移动距离满足要求。

原题:
Farmer John has N (2 <= N <= 1,500) prize milk cows conveniently numbered 1..N. His newly-painted barn has S (N <= S <= 1,000,000) stalls (conveniently numbered 1..S) in a single long line; each stall is a unit distance from its neighboring stall(s).

The cows have made their way to the stalls for a rest; cow i is in stall P_i. Antisocial as they are, the cows get grumpy if they are situated in stalls very close to each other, so Farmer John wants to move the cows to be as spread out as possible.

FJ wants to make sure that the N - 1 distances between adjacent cows are as large as possible, and he would also like them to be similar to each other (i.e., close to equi-distant spacing).

In particular, FJ would like all distances between adjacent cows to be at most 1 different from (S - 1) / (N - 1), where integer division is used. Moreover, he would like as many of these distances as possible to be exactly equal to (S - 1) / (N - 1) [integer division]. Thus, with four cows and eight stalls, one can place the cows at positions 1, 3, 5, 8 or 1, 3, 6, 8 but not at 1, 2, 4, 7 or 1, 2, 4, 8.

Help FJ spread the cows as efficiently as possible by calculating and reporting the minimum total distance that the cows have to move in order to achieve proper spacing. Ignore the distance it takes for a cow to enter or exit a stall.

Input

  • Line 1: Two space-separated integers: N and S

  • Lines 2..N+1: Line i+1 contains the single integer: P_i

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

Output

  • Line 1: A single integer: the minimum total distance the cows have to travel. This number is guaranteed to be under 1,000,000,000 (thus fitting easily into a signed 32-bit integer).
      输出一个整数表示最少移动距离。

Sample Input

5 10
2
8
1
3
9

Sample Output

4

Data Constraint

Hint

【样例说明】
1 2 3 4 5 6 7 8 9 10
Init Stall | A | B | C | . | . | . | . | D | E | . |
Final Stall | A | . | B | . | C | . | . | D | . | E |
Distance moved | 0 | . | 1 | . | 2 | . | . | 0 | . | 1 |这里写图片描述

思路:
题目中没有说明两个条件:第一位和最后一位必须有牛棚,所以就DP啦

pascal:

type arr=array[0..1500] of longint;
var n,s,i,j,l,x,y:longint;
a:arr;
f:array[0..1500,0..1500] of longint;
function min(x,y:longint):longint;
begin
    if x<y then exit(x) else exit(y);
end;
procedure dg();
begin
    for i:=2 to n do
    begin
        s:=min(i-1,y);
        f[i,0]:=f[i-1,0]+abs(a[i]-i*x+x-1);
        for j:=1 to s do f[i,j]:=min(f[i-1,j-1],f[i-1,j])+abs(a[i]-i*x+x-j-1);
    end;
end;
procedure chuli();
var i,j:longint;
begin
    for i:=0 to 1500 do
    begin
        for j:=0 to 1500 do
        begin
            f[i,j]:=maxlongint div 3;
        end;
    end;
    f[1,0]:=a[1]-1;
    x:=(s-1)div(n-1);
    y:=(s-1)mod(n-1);
end;
procedure qsort_min_max(l,r:longint; var px:arr);
var i,j,mid:longint;
begin
    i:=l;
    j:=r;
    mid:=px[(i+j) div 2];
    while i<=j do
    begin
        while px[i]<mid do inc(i);
        while px[j]>mid do dec(j);
        if i<=j then
        begin
            px[0]:=px[i];
            px[i]:=px[j];
            px[j]:=px[0];
            inc(i);
            dec(j);
        end;
    end;
    if i<r then qsort_min_max(i,r,px);
    if l<j then qsort_min_max(l,j,px);
end;
procedure init();
begin
    readln(n,s);
    for i:=1 to n do readln(a[i]);
    qsort_min_max(1,n,a);
    chuli();
    dg();
    writeln(f[n,y]);
end;
begin
    assign(input,'graze2.in');reset(input);
    assign(output,'graze2.out');rewrite(output);

    init();

    close(input);close(output);
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值