总结
1. [i~j] 之间建立一个邮局, 位置是 (i+j+1)/2
2. 初始化, 尽可能少的初始化
代码
/* * source.cpp * * Created on: 2014-4-5 * Author: vincent */ #include <iostream> #include <stdio.h> #include <math.h> #include <memory.h> using namespace std; const int NUM = 310; const int INF = 0X3F3F3F3F; int arr[10010]; int dist[NUM][NUM]; int dp[NUM][31]; void init(int n) { for(int i = 1; i <= n; i ++) { for(int j = i; j <= n; j ++) { int mid = (i+j+1) >> 1; int sum = 0; for(int k = i; k <= j; k ++) sum += abs(arr[k] - arr[mid]); dist[i][j] = sum; } } } int cal(int n, int m) { memset(dp, 0X3F, sizeof(dp)); for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { if(j >= i) { dp[i][j] = 0; continue; } dp[i][j] = dist[1][i]; //cout << dp[i][j] << endl; for(int k = 1; k < i; k ++) { dp[i][j] = min(dp[i][j], dp[k][j-1] + dist[k+1][i]); } } } return dp[n][m]; } int main() { freopen("C:\Users\vincent\Dropbox\workplacce\joj\test.txt", "r", stdin); int n, m; while(scanf("%d%d", &n, &m) != EOF) { for(int i = 1; i <= n; i ++) scanf("%d", arr+i); init(n); int res = cal(n, m); printf("%d ", res); } return 0; }