题目
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
Hint
分析
dp
状态转移方程:
f[i][j]=min(f[i-1][j-1],f[i-1][j])+abs(a[i]-i*x+x-j-1);
CODE
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,s,a[2000],f[2000][2000];
bool cmp(int a,int b){
return a<b;
}
int main(){
freopen("gwraze2.in","r",stdin);
freopen("graze2.out","w",stdout);
scanf("%d%d",&n,&s);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1,cmp);
memset(f,0x3f3f3f,sizeof(f));
f[1][0]=a[1]-1;
int x=(s-1)/(n-1);
int y=(s-1)%(n-1);
for (int i=2;i<=n;i++){
s=min(i-1,y);
f[i][0]=f[i-1][0]+abs(a[i]-i*x+x-1);
for (int j=1;j<=s;j++)
f[i][j]=min(f[i-1][j-1],f[i-1][j])+abs(a[i]-i*x+x-j-1);
}
printf("%d\n",f[n][y]);
return 0;
}