2004112 2006-08-06 23:32:06 Accepted 1196 C++ 00:00.02 704K St.Crux dis[i][k]表示在前k+1个加油站(0-k)中放入(i+1)个补给站所最小达到的距离和。 cost[i][k]表示从点i到点k所需要的最短距离,当且仅当补给站放在i,k的中点时。 方程是dis[i][k] = min(dis[i - 1][j] + cost[j + 1][k]) i - 1 <= j <k C++的数组下标真是头痛哪 #include <cstdio>#include <string>#include <cmath> int d[201][201], s[201][201], a[201], n, m;#define MX 99999999 int main(){ //freopen("in.txt", "r", stdin); int c = 0; while(scanf("%d %d", &n, &m) && n) { printf("Chain %d\n", ++ c); int i, k, j; for(i = 0; i < n; i ++) { scanf("%d", &a[i]); } memset(s, 0, sizeof(s)); for(i = 0; i < n; i ++) { for(k = i; k < n; k ++) { int mid = (i + k) / 2; for(j = i; j <= k; j ++) { s[i][k] += abs(a[j] - a[mid]); } } } for(i = 0; i < m; i ++) { for(k = 0; k < n; k ++) { d[i][k] = MX; } } for(i = 0; i < n; i ++) { d[0][i] = s[0][i]; } for(i = 1; i < m; i ++) { for(k = i; k < n; k ++) { if(k == i) { d[i][k] = 0; continue; } for(j = i - 1; j < k; j ++) { if(d[i - 1][j] + s[j + 1][k] < d[i][k]) d[i][k] = d[i - 1][j] + s[j + 1][k]; } } } printf("Total distance sum = %d\n", d[m - 1][n - 1]); printf("\n"); } return 0;}

评论