662 - Fast Food

来源:互联网 发布:免费申请淘宝账号注册 编辑:程序博客网 时间:2024/05/17 09:10
/*首先预处理用w[i][j]表示从i到j的最小距离和用d[i][j]表示用在前i个饭店中选j个仓库的最小距离和状态转移方程d[i][j]=min(d[k][j-1]+w[k+1][i])  k:1->i-1;然后递归打印路径,如果用非递归的话要记录一下。 */#include <stdio.h>#include <string.h>#define maxn 205int r[maxn],d[maxn][35],w[maxn][maxn],n,k;int abs(int a){if(a<0) return -a;else return a;}int min(int a,int b){if(a<b) return a;else return b;}void dp(){for(int i=0;i<n;i++)for(int j=0;j+i<n;j++){for(int k=j;k<=i+j;k++)w[j][i+j]+=abs(r[k]-r[(i+j+j)/2]);}for(int i=0;i<n;i++)d[i][1]=w[0][i];for(int i=2;i<=k;i++){for(int j=i-1;j<n;j++){for(int k=i-2;k<j;k++)d[j][i]=min(d[j][i],d[k][i-1]+w[k+1][j]);}}}void printpath(int a,int b,int sum,int c){if(c==1){ if(a==b)printf("Depot %d at restaurant %d serves restaurant %d\n",c,b+1,b+1);elseprintf("Depot %d at restaurant %d serves restaurants %d to %d\n",c,(a+b)/2+1,a+1,b+1);return;}for(int i=a;i<b;i++)if(d[i][c-1]+w[i+1][b]==sum){printpath(0,i,d[i][c-1],c-1);if(i+1==b)printf("Depot %d at restaurant %d serves restaurant %d\n",c,b+1,b+1);elseprintf("Depot %d at restaurant %d serves restaurants %d to %d\n",c,(i+1+b)/2+1,i+1+1,b+1);break;}}int main(){int t=0;while(scanf("%d%d",&n,&k)&&!(n==0&&k==0)){for(int i=0;i<n;i++)scanf("%d",&r[i]);memset(d,0x7f,sizeof(d));memset(w,0,sizeof(w));dp();printf("Chain %d\n",++t);printpath(0,n-1,d[n-1][k],k);printf("Total distance sum = %d\n",d[n-1][k]);printf("\n");}return 0;}


 

原创粉丝点击