HDOJ 1227 DP
这题参考了别人的思路。
dist是二维数组。dist[i,j]存放“如果i和j两个restaurants之间只有一个depot,则它们之间(包括i和j)的所有restaurants到这个depot的路径之和的最小值”。
ans是二维数组,ans[i,j]存放“为i个restaurants配置j个depots,这i个restaurants到最近的depots的距离之和的最小值”。
则DP转移函数为,ans[i,j]=min{ans[k][j-1]+dist[k+1][i]},j-1<=k<=i-1。也就是说,为前k个restaurants配置j-1个depots,为第k+1~第i个restaurants配置一个depot,选取一个k,使得总距离之和最小。
#include <iostream> using namespace std; const int N = 205; const int K = 35; int ans[N][K]; int pos[N]; int dist[N][N];/* 若只有一个depot,i,j间的restaurants到这个depot的距离之和的最小值 */ void initDist(int n) { memset(dist,0,sizeof(dist)); for (int i = 1;i <= n;i ++) for (int j = i;j <= n;j ++) { int mid = (i + j) / 2; for (int m = i;m <= j;m ++) dist[i][j] += abs(pos[mid] - pos[m]); } } int main () { int n,k; int caseNum = 1; while (scanf("%d%d",&n,&k) != -1) { if (n == 0 && k == 0) break; for (int i = 1;i <= n;i ++) scanf("%d",&pos[i]); initDist(n); memset(ans,0,sizeof(ans)); for (int i = 1;i <= n;i ++) ans[i][1] = dist[1][i]; for (int j = 2;j <= k;j ++) { for (int i = j;i <= n;i ++) { int min = -1; for (int m = j - 1;m <= i -1;m ++) { int temp = ans[m][j - 1] + dist[m + 1][i]; if (min == -1) min = temp; else min = min < temp ? min : temp; } ans[i][j] = min; } } printf("Chain %d\n",caseNum); caseNum ++; printf("Total distance sum = %d\n\n",ans[n][k]); } return 0; }

浙公网安备 33010602011771号