UVA 662 Fast Food
2011-12-04 22:24
176 查看
UVA_662
首先我们考虑区间[i,j]内如果建一个餐馆应该建在哪个位置,比较容易证明应该是建在中间的位置,如果是偶数个元素,中间两个位置随便一个都可以。这样我们就可以预处理出区间[i,j]内建一个餐馆的最小总路程A[i][j]了。
我们可以用f[i][j]表示第i个餐馆服务到第j个位置所需的最小总路程,那么f[i][j]=min{f[i-1][k]+A[k+1][j]},其中i-1<=k<j。
首先我们考虑区间[i,j]内如果建一个餐馆应该建在哪个位置,比较容易证明应该是建在中间的位置,如果是偶数个元素,中间两个位置随便一个都可以。这样我们就可以预处理出区间[i,j]内建一个餐馆的最小总路程A[i][j]了。
我们可以用f[i][j]表示第i个餐馆服务到第j个位置所需的最小总路程,那么f[i][j]=min{f[i-1][k]+A[k+1][j]},其中i-1<=k<j。
#include<stdio.h> #include<string.h> #define MAXD 210 #define MAXK 40 #define INF 0x3f3f3f3f int N, K, f[MAXK][MAXD], p[MAXK][MAXD], a[MAXD], b[MAXD]; int A[MAXD][MAXD], s[MAXD]; int init() { int i, j, k, temp; scanf("%d%d", &N, &K); if(!N && !K) return 0; s[0] = 0; for(i = 1; i <= N; i ++) { scanf("%d", &a[i]); s[i] = a[i] + s[i - 1]; } for(i = 1; i <= N; i ++) for(j = i; j <= N; j ++) { k = (i + j) / 2; temp = s[j] - s[k] - (j - k) * a[k]; temp += (k - i) * a[k] - s[k - 1] + s[i - 1]; A[i][j] = temp; } return 1; } void printpath(int k, int n) { int t = p[k] ; if(k != 1) printpath(k - 1, t); printf("Depot %d at restaurant %d serves restaurants %d to %d\n", k, (t + 1 + n) / 2, t + 1, n); } void solve() { int i, j, k, min; memset(f, 0x3f, sizeof(f)); for(k = 1; k <= N; k ++) f[1][k] = A[1][k]; for(i = 2; i <= K; i ++) for(j = i; j <= N; j ++) for(k = i - 1; k < j; k ++) { if(f[i - 1][k] + A[k + 1][j] < f[i][j]) { f[i][j] = f[i - 1][k] + A[k + 1][j]; p[i][j] = k; } } printpath(K, N); printf("Total distance sum = %d\n", f[K] ); } int main() { int t = 0; while(init()) { printf("Chain %d\n", ++ t); solve(); printf("\n"); } return 0; }
相关文章推荐
- uva 662 - Fast Food
- UVA 662 - Fast Food
- uva 662 Fast Food
- UVA - 662 Fast Food
- Problem W UVA 662 二十三 Fast Food
- UVA662- Fast Food
- UVA 662 Fast Food
- uva_662 - Fast Food( 区间DP )
- UVA - 662
- UVA - 662 Fast Food 区间DP
- uva 662(区间dp)
- dp( UVa 662 Fast Food )
- uva 662 - Fast Food(dp)
- UVA - 662 Fast Food
- 小白dp uva 662 - Fast Food (除夕夜的博客 ^ ^)
- uva 662 Fast Food
- uva 662
- UVA 662 Fast Food 区间DP
- uva 662 - Fast Food
- UVA 607 Fast Food