这里需要一个常识:在i到j取一点使它到区间每一点的距离之和最小,这一点为(i+j)/2用图形即可证明;
Dp[i][j]=max{Dp[i-1][k]+cost[k+1][j] 其中,(i-1)<=k<j状态为前j个position建i个depots
代码很容易编写:
#include <iostream>
#include <cmath>
using namespace std;
const int N = 205;
const int M = 32;
int dp[M][N];
int pos[N];
int cost(int x, int y)
{
int t = (x + y) / 2;
int sum = 0;
for(int i = x; i <= y; i++)
{
sum += abs(pos[i] - pos[t]);
}
return sum;
}
int main()
{
int n, m;
int t = 1;
while(cin >> n >> m, n)
{
memset(dp, 999999, sizeof(dp));
for(int i = 1; i <= n; i++)
cin >> pos[i];
for(int i = 1; i <= n; i++)
dp[1][i] = cost(1, i);
for(int i = 2; i <= m; i++)
{
for(int j = 1; j <=n; j++)
{
for(int k = i -1; k < j; k++)
{
dp[i][j] = min(dp[i-1][k] + cost(k+1, j), dp[i][j]);
}
}
}
cout <<"Chain "<< t++ << endl;
cout <<"Total distance sum = " << dp[m][n] << endl << endl;
}
return 0;
}