poj 1160
来源:互联网 发布:用友erp软件价格 编辑:程序博客网 时间:2024/06/10 03:09
/* V个村庄,选出P个点要求距离最短。想到dp方程,dp[i][j],表示前i个村庄中放置j个邮局所需的费用 dp[i][j] = min(dp[i][j],dp[k][j-1] + sum[k+1][j]); sum表示i和j之间,放置一个邮局的话最小的费用,此时放到最中间为最小费用*/#include<stdio.h>#include<string.h>#define inf 99999999int villages[310];int dp[310][310];int sum[310][310];int min(int x,int y){ if(x<y) return x; return y; }int main(){ int n,p; int i,j; while(scanf("%d%d",&n,&p)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&villages[i]); for(i=1;i<n;i++) for(j=i+1;j<=n;j++) sum[i][j]=sum[i][j-1]+villages[j]-villages[(i+j)/2]; //此处有点技巧 memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { dp[i][i]=0; dp[i][1]=sum[1][i]; } for(j=2;j<=p;j++) { for(i=j+1;i<=n;i++) { dp[i][j]=inf; for(int k=j-1;k<i;k++) { dp[i][j]=min(dp[i][j],dp[k][j-1]+sum[k+1][i]); } } } printf("%d\n",dp[n][p]); } return 0; }