【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]);

 

View Code
 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 }

 

              

posted @ 2013-04-15 22:20  Mr. Ant  阅读(225)  评论(0编辑  收藏  举报