/*
V个村庄,选出P个点要求距离最短。想到dp方程,dp[i][j],表示前i个村庄中放置j个邮局所需的费用
dp[i][j] = min(dp[i][j],dp[k][j-1] + sum[k+1][j]);
sum表示i和j之间,放置一个邮局的话最小的费用,此时放到最中间为最小费用
*/
#include<stdio.h>
#include<string.h>
#define inf 99999999
int villages[310];
int dp[310][310];
int sum[310][310];
int min(int x,int y)
{
if(x<y) return x;
return y;
}
int main()
{
int n,p;
int i,j;
while(scanf("%d%d",&n,&p)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&villages[i]);
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
sum[i][j]=sum[i][j-1]+villages[j]-villages[(i+j)/2]; //此处有点技巧
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
dp[i][i]=0;
dp[i][1]=sum[1][i];
}
for(j=2;j<=p;j++)
{
for(i=j+1;i<=n;i++)
{
dp[i][j]=inf;
for(int k=j-1;k<i;k++)
{
dp[i][j]=min(dp[i][j],dp[k][j-1]+sum[k+1][i]);
}
}
}
printf("%d\n",dp[n][p]);
}
return 0;
}
poj 1160
最新推荐文章于 2021-03-25 23:29:42 发布