1694: [Usaco2007 Demo]Grazing on the Run

1694: [Usaco2007 Demo]Grazing on the Run

Time Limit: 5 Sec   Memory Limit: 64 MB
Submit: 147   Solved: 94
[ Submit][ Status][ Discuss]

Description

A long, linear field has N (1 <= N <= 1,000) clumps of grass at unique integer locations on what will be treated as a number line. Think of the clumps as points on the number line. Bessie starts at some specified integer location L on the number line (1 <= L <= 1,000,000) and traverses the number line in the two possible directions (sometimes reversing her direction) in order to reach and eat all the clumps. She moves at a constant speed (one unit of distance in one unit of time), and eats a clump instantly when she encounters it. Clumps that aren't eaten for a while get stale. We say the ``staleness'' of a clump is the amount of time that elapses from when Bessie starts moving until she eats a clump. Bessie wants to minimize the total staleness of all the clumps she eats. Find the minimum total staleness that Bessie can achieve while eating all the clumps.

Input

* Line 1 : Two space-separated integers: N and L. * Lines 2..N+1: Each line contains a single integer giving the position P of a clump (1 <= P <= 1,000,000).

Output

* Line 1: A single integer: the minimum total staleness Bessie can achieve while eating all the clumps.

Sample Input


4 10
1
9
11
19

INPUT DETAILS:

Four clumps: at 1, 9, 11, and 19. Bessie starts at location 10.

Sample Output


44

OUTPUT DETAILS:

Bessie can follow this route:

* start at position 10 at time 0
* move to position 9, arriving at time 1
* move to position 11, arriving at time 3
* move to position 19, arriving at time 11
* move to position 1, arriving at time 29

giving her a total staleness of 1+3+11+29 = 44. There are other routes
with the same total staleness, but no route with a smaller one.



显然牛每次吃完一棵草都是在某个区间的左/右端点。。因为把路过的草吃掉总比不吃来得好
那么这题就变成一道区间dp,设f[i][j][k]为区间[i,j]在k(左,右)端点的最小值
然后。。。没啦!
所以区间dp是建立在比它更小的区间上完成的~

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<cstdlib>
#include<map>
#include<cmath>
using namespace std;

const int maxn = 1e3 + 10;
typedef long long LL;

LL f[maxn][maxn][2],a[maxn],n,i,j,s;

int main()
{
	#ifndef ONLINE_JUDGE
	#ifndef YZY
	  freopen(".in","r",stdin);
	  freopen(".out","w",stdout);
	#else
	  freopen("yzy.txt","r",stdin);
	#endif
	#endif

	cin >> n >> s;
	for (i = 1; i <= n; i++) scanf("%d",&a[i]);
	sort (a + 1,a + n + 1);
	memset(f,127,sizeof(f));
	for (i = 1; i <= n; i++) f[i][i][0] = f[i][i][1] = abs(a[i] - s) * n;
	for (int l = 2; l <= n; l++)
	  for (i = 1; i <= n - l + 1; i++)
	  {
	  	j = i + l - 1;
	  	f[i][j][0] = min(f[i][j][0],f[i+1][j][0] + abs(a[i+1] - a[i]) * (n-l+1));
	  	f[i][j][0] = min(f[i][j][0],f[i+1][j][1] + abs(a[j] - a[i]) * (n-l+1));
	  	f[i][j][1] = min(f[i][j][1],f[i][j-1][0] + abs(a[i] - a[j]) * (n-l+1));
	  	f[i][j][1] = min(f[i][j][1],f[i][j-1][1] + abs(a[j] - a[j-1]) * (n-l+1));
	  }
	cout << min(f[1][n][0],f[1][n][1]);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值