动态规划,用c[i][j]表示在i和j之间建一个仓库花费的最小距离,注意:ij之间建仓库要使距离最小应该建在a[(i+j)/2]上。
dp[i][j]表示前j个店建i个仓库的最小距离。状态转移方程:dp[i][j]=min{dp[i-1][k]+c[k+1][j]}(k=i-1,i,...,j-1。)
代码:
#include<stdlib.h>
#include<limits.h>
#include<string.h>
#include<stdio.h>
int main()
{
int dp[202][202],c[202][202];
int n,m,a[202],tt=1;
while(scanf("%d%d",&n,&m),n,m)
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(dp,0,sizeof(dp));
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
for(int k=i;k<=j;k++)
{
c[i][j]+=abs(a[k]-a[(i+j)/2]);
}
//printf("c%d %d %d\n",i,j,c[i][j]);
}
}
for(int i=1;i<=n;i++)
{
dp[1][i]=c[1][i];
}
for(int i=2;i<=m;i++)
{
for(int j=i+1;j<=n;j++)
{
int m=INT_MAX;
for(int k=i-1;k<j;k++)
{
if(m>dp[i-1][k]+c[k+1][j])
m=dp[i-1][k]+c[k+1][j];
}
dp[i][j]=m;
//printf("dp%d %d %d\n",i,j,dp[i][j]);
}
}
printf("Chain %d\n",tt++);
printf("Total distance sum = %d\n",dp[m][n]);
printf("\n");
}
}