poj 1160(dp)


Post Office
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 10824 Accepted: 5801

Description

There is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each village is identified with a single integer coordinate. There are no two villages in the same position. The distance between two positions is the absolute value of the difference of their integer coordinates. 

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

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

Input

Your program is to read from standard input. The first line contains two integers: the first is the number of villages V, 1 <= V <= 300, and the second is the number of post offices P, 1 <= P <= 30, P <= V. The second line contains V integers in increasing order. These V integers are the positions of the villages. For each position X it holds that 1 <= X <= 10000.

Output

The first line contains one integer S, which is the sum of all distances between each village and its nearest post office.

Sample Input

10 5 1 2 3 6 7 9 11 22 44 50

Sample Output

9

Source

IOI 2000

今天老师讲的dp,回来写写,坑爹啊,做了近3个钟,先是在找中点的时候,把+写成了-号,悲剧啊,找了近半个钟,后来数组范围写反了,结果悲剧了两个钟。。。
好吧,写一下解题思路,这题题意是在一条街道上有n个住户,在这条建造m个邮局,每个用户会到最近的邮局,寄东西,求所有的用户到邮局之和最小。先分析一下数据范围,1<n<300,1<m<30,不是很大,暴力的话300的30次方,肯定不行,像这种最优解问题,很自然的想到dp,显然题中状态是m个邮局与n居民的距离之和最小,设计一个二维数组,dp[i][j],i表示 邮局数,j表示居民数。。。转移方程dp[i][j]=min(dp[i][j],dp[i-1][k]+cost[k][j])(1<k<j),这里有个小优化,就是i-1<k<j,因为k个邮局覆盖k个居民才有意义,k<i-1的时候都为0,没有意义。
下面是我的代码

#include<cstdio>
#include<string>
#include<cmath>
int cost[305][305],dp[35][305],n,m;
int DP()
{
	int tem,i,j,k;
	for(i=1;i<=n;i++)
	{
		dp[1][i]=cost[1][i];
	}
	for(i=2;i<=m;i++)
		for(j=2;j<=n;j++)
		{
			dp[i][j]=0x7fffffff;
			for(k=i-1;k<=j;k++)
				if(dp[i][j]>dp[i-1][k]+cost[k+1][j])
					dp[i][j]=dp[i-1][k]+cost[k+1][j];
		}
		return dp[m][n];
}
int main()
{
	int i,j,k,s[305];
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);
	}
	for(i=1;i<=n;i++)
		for(j=i+1;j<=n;j++)
		{
			for(k=i;k<=j;k++)
				cost[i][j]+=abs(s[k]-s[(i+j)/2]);
		}
		printf("%d\n",DP());
		return 0;
}


你可能感兴趣的:(Integer,Office,input,each,output,distance)