您的位置:首页 > 其它

【HDU1227 Fast Food】经典DP

2013-04-15 22:20 239 查看
题目链接: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

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn=225;
const int oo=0x3fffffff;
int dp[maxn][maxn], cost[maxn][maxn];
int a[maxn];

int main()
{
int n, K, tcase=0;
while(cin >> n >> K,n+K)
{
memset(cost,0,sizeof(cost));
for(int i=1; i<=n; i++) scanf("%d",a+i);
sort(a+1,a+n+1);
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
for(int k=j; k<=i; k++)
cost[j][i]+=abs(a[k]-a[(i+j)/2]);
for(int i=1; i<=n; i++)
for(int j=1; j<=K; j++) dp[i][j]=oo;
for(int i=1; i<=n; i++) dp[i][1]=cost[1][i];
for(int k=2; k<=K; k++)
for(int i=k; i<=n; i++)
for(int j=k-1; j<i; j++)
dp[i][k]=min(dp[i][k],dp[j][k-1]+cost[j+1][i]);
printf("Chain %d\nTotal distance sum = %d\n\n",++tcase,dp
[K]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: