【HDU1227 Fast Food】经典DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1227
题目大意:有n个餐馆和k个仓库,每个餐馆都要有一个仓库负责送货,每个仓库可以送货给多个餐馆,仓库可以放在任意餐馆的位置,问你哪个仓库给那些餐馆送货能使总的送货距离最小。
解题思路: dp[i][k]表示前i个餐馆需要k个仓库送货,假设i,j餐馆之间需要设一个仓库,日常联想就可知道设在i,j的"中间"即是最小值了,dp[i][k]可由状态dp[j][k-1]个状态更新而来,dp[j][k-1]表示的是前j个餐馆(j<i)需要k-1个仓库,还要加上第个j+1餐馆-->第i个餐馆之间再设一个仓库的最小距离cost[j+1][i]。
推敲之后可得状态转移方程:dp[i][k]=min(dp[i][k],dp[j][k-1]+cost[j+1][i]);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn=225; 8 const int oo=0x3fffffff; 9 int dp[maxn][maxn], cost[maxn][maxn]; 10 int a[maxn]; 11 12 int main() 13 { 14 int n, K, tcase=0; 15 while(cin >> n >> K,n+K) 16 { 17 memset(cost,0,sizeof(cost)); 18 for(int i=1; i<=n; i++) scanf("%d",a+i); 19 sort(a+1,a+n+1); 20 for(int i=1; i<=n; i++) 21 for(int j=1; j<=i; j++) 22 for(int k=j; k<=i; k++) 23 cost[j][i]+=abs(a[k]-a[(i+j)/2]); 24 for(int i=1; i<=n; i++) 25 for(int j=1; j<=K; j++) dp[i][j]=oo; 26 for(int i=1; i<=n; i++) dp[i][1]=cost[1][i]; 27 for(int k=2; k<=K; k++) 28 for(int i=k; i<=n; i++) 29 for(int j=k-1; j<i; j++) 30 dp[i][k]=min(dp[i][k],dp[j][k-1]+cost[j+1][i]); 31 printf("Chain %d\nTotal distance sum = %d\n\n",++tcase,dp[n][K]); 32 } 33 return 0; 34 }