(DP) HDU 1227 Fast Food

/*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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章