(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;
}

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