jzoj1298. 牛棚

题目

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值