POJ 1160 Post Office

Description

There is a straight highwaywith villages alongside the highway. The highway is represented as an integeraxis, and the position of each village is identified with a single integercoordinate. There are no two villages in the same position. The distancebetween two positions is the absolute value of the difference of their integercoordinates.

Post offices will be built in some, but not necessarily all of the villages. Avillage and the post office in it have the same position. For building the postoffices, their positions should be chosen so that the total sum of alldistances between each village and its nearest post office is minimum.

You are to write a program which, given the positions of the villages and thenumber of post offices, computes the least possible sum of all distancesbetween each village and its nearest post office.

Input

Your program is to read fromstandard input. The first line contains two integers: the first is the numberof villages V, 1 <= V <= 300, and the second is the number of postoffices P, 1 <= P <= 30, P <= V. The second line contains V integersin increasing order. These V integers are the positions of the villages. Foreach position X it holds that 1 <= X <= 10000.

Output

The first line contains oneinteger S, which is the sum of all distances between each village and itsnearest post office.

Sample Input

10 5

1 2 3 6 7 9 11 22 44 50

Sample Output

9

题目简介:在坐标轴上有V个村庄。现在要修P个邮局。村庄i在坐标轴上的坐标为Xi,以从小到大输入。问各个村庄到邮局最近的总路程为多少。

方法:动态规划。f[i][j]表示修j个邮局,且最后修在第i个村庄。f[i][j]= min{f[r][j-1]+sum[r+1][i]};即最小的应该是,前面修j-1个邮局,且最后一个修在第r个村庄+最后一个邮局修在r+1和i之间的最小值。不知道怎么说了,动态规划是硬伤。。。。太难想了!!!!!

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INF 99999999

int f[310][31];
int dis[310];
int sum[310][310];

int main()
{
	int V, P;
	int i, j, k;
	while(scanf("%d%d",&V, &P)!=EOF)
	{
		memset(f,0,sizeof(f));
		memset(sum,0,sizeof(sum));

		for(i = 1;i<=V;i++)
		{
			scanf("%d",&dis[i]);
		}


		for(i = 1;i<=V;i++)
		{
			for(j = i+1;j<=V;j++)
			{
				sum[i][j] = sum[i][j-1] + dis[j] - dis[(i+j)/2];
			}
		}//在第i个村庄和第j个村庄之间修1个邮局最小的总距离


		for(i = 1;i<=V;i++)
		{
			f[i][i] = 0;
			f[i][1] = sum[1][i];
		}//只修一个邮局,修在第i个村庄


		for(i = 2;i<=P;i++)
		{
			for(j = i+1;j<=V;j++)
			{
				f[j][i] = INF;
				for(k = i-1;k<j;k++)
				{
					if(f[j][i] > f[k][i-1] + sum[k+1][j])//前k个村庄修i-1个邮局,最后一个邮局修在第k+1个村庄和第j个村庄之间
					{
						f[j][i] = f[k][i-1] + sum[k+1][j];
					}
				}
			}
		}//f[j][i]表示最后一个邮局修在第j个村庄,一共修i个邮局

		printf("%d\n",f[V][P]);
	}
	return 0;
}


 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值