记录编号 263743 评测结果 AAAAAAAAAA
题目名称 [IOI 2000]邮局 最终得分 100
用户昵称 Gravatar洛克索耶夫 是否通过 通过
代码语言 C++ 运行时间 0.018 s
提交时间 2016-05-26 09:36:52 内存使用 1.63 MiB
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;

int Read()
{
	int a = 0, minus = 1;
	char ch = getchar(); 
	while(ch < '0' || ch > '9'){
		ch = getchar();
		if(ch == '-')	minus= -1;
	}
	while(ch >= '0' && ch <= '9'){
		a = a * 10 + ch - '0';
		ch = getchar();
	}
	return a * minus;
}

inline int GetMin(const int& a, const int& b)
{
	return a < b ? a : b;
}

inline int Abs(const int& a)
{
	if(a < 0)	return -a;
	return a;
}

int a[4000] = {0}, f[400][50] = {0}, b[400][400] = {0}, d[400][400] = {0};
//f[i][j]:前i个村庄建立j个邮局的最优 
//a[i]:第i个村庄的位置
//b[i][j]:第i个村庄到第j个村庄的距离 
//d[i][j]:第i个村庄到第j个村庄只建立一个邮局的最小距离

int main()
{
	freopen("postoffice.in", "r", stdin);
	freopen("postoffice.out", "w", stdout);
	memset(f, 0x7f, sizeof(f));
	int V = Read(), P = Read();
	for(int i = 1; i <= V; i++)	a[i] = Read();
	for(int i =1; i <= V; i++)
		for(int j = 1; j <= V; j++)
			b[i][j] = Abs(a[j] - a[i]);	
	for(int i = 1; i <= V; i++)
		for(int j = i; j <= V; j++){
			for(int k = i; k <= j; k++){
				d[i][j] += b[(i + j) / 2][k];//初始化?
			}
		}
	for(int i = 1; i <= V; i++)	f[i][1] = d[1][i];	
//	for(int i =1; i <= V; i++)
//		for(int j = 1; j <= V; j++){
//			printf("%d ", d[i][j]);
//			if(j == V)	printf("\n");
//		}		
			 
	for(int i = 1; i <= V; i++)
		for(int j = 1; j <= P; j++)
			for(int k = 1; k < i; k++) 
				f[i][j] =GetMin(f[i][j], f[k][j - 1] + d[k + 1][i]);
			//从k断开,前边建立j-1个邮局,后边建立1个 
	
	int ans = f[V][P];
	printf("%d", f[V][P]);	 
	return 0;
}