标签:
题意:
X轴上有N个餐馆。位置分别是D[1]...D[N]。
有K个食物储存点。每一个食物储存点必须和某个餐厅是同一个位置。
计算SUM(Di-(离第i个餐厅最近的储存点位置))的最小值。
1 <= n <= 200, 1 <= k <= 30, k <= n
思路:
第K个储存点的位置如果确定,前K-1个储存点的位置是浮动的。有很多的重复子结构。DP的结构很明显。
dp[i][j]:第i个储存点放在第j个餐馆的位置所得到的最小值。
代码:
int n,k; int pos[205]; int dp[35][205]; int calc(int pre,int now){ int ans=0; rep(i,pre,now){ ans+=min( pos[i]-pos[pre],pos[now]-pos[i] ); } return ans; } int calc2(int last){ int ans=0; rep(i,last,n){ ans+=(pos[i]-pos[last]); } return ans; } int main(){ int T=0; while(scanf("%d%d",&n,&k)!=EOF,n||k){ rep(i,1,n) scanf("%d",&pos[i]); sort(pos+1,pos+1+n); mem(dp,inf); dp[1][1]=0; rep(now,1,n-k+1){ dp[1][now]=0; rep(j,1,now-1){ dp[1][now]+=(pos[now]-pos[j]); } } rep(i,2,k){ //第i个depot rep(now,i,n-k+i){ //第i个depot放置的编号 rep(pre,i-1,now-1){ //第i-1个depot放置的编号 dp[i][now]=min( dp[i][now],dp[i-1][pre]+calc(pre,now) ); } } } int ans=inf; rep(last,k,n){ ans=min( ans,dp[k][last]+calc2(last) ); } printf("Chain %d\n",++T); printf("Total distance sum = %d\n\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/fish7/p/4330047.html