/*dp[i][j]=min(dp[i][j],dp[k][j-1]+d[k+1][i])
dp[k][j-1] 表示从k个饭店中建立j-1个仓库
d[k+1][i] 表示从第k+1个饭店到第i个饭店之间建立一个仓库最短距离
*/
#include <iostream>
#include <cstdio>
#define INF 1000000
#define min(a,b) a<b?a:b
using namespace std;
int dp[365][30]; //表示在i个饭店之间建立j个仓库
int d[365][365]; //表示两个饭店之间建立一个仓库的最短距离
int a[365];
int main()
{
int n,m;
int i,j,k;
int t=0;
while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
{
memset(d,0,sizeof(d)); //将d数组初始化为0
t++;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
/*任意两点之间建立一个仓库的最短距离*/
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
for(k=i;k<=j;k++)
{
d[i][j]+=abs(a[k]-a[(i+j)/2]);
}
}
}
/*初始化dp数组*/
for(i=0;i<365;i++)
{
for(j=0;j<35;j++)
{
dp[i][j]=INF;
}
}
/*从第一个饭店到任意饭店之间建立一个仓库所需最短距离*/
for(i=1;i<=n;i++)
{
dp[i][1]=d[1][i];
}
for(j=2;j<=m;j++) //从建立第二个仓库开始,直到建立m个仓库为止
{
for(i=j;i<=n;i++) //此处i=j,因为如果建立j个仓库至少需要i个饭店,此处是一个剪枝,i也可以从1开始
{
for(k=j-1;k<i;k++) //k用来表示k个饭店以前建立j-1个仓库,从k以后到第i个饭店之间建立一个仓库,此处,k=j-1是剪枝,也可以从1开始
{
dp[i][j]=min(dp[i][j],dp[k][j-1]+d[k+1][i]);
}
}
}
printf("Chain %d\nTotal distance sum = %d\n\n",t,dp[n][m]);
}
return 0;
}
(DP) HDU 1227 Fast Food
最新推荐文章于 2020-12-20 17:30:37 发布