您的位置:首页 > 其它

动态规划-hdu1227Fast Food

2016-01-28 23:31 246 查看
题意:

从n个地方选取k个地方,定义某个点的"距离"为 该点到k个点的距离 的最小值。 求n个点"距离"的最小值。

思路:

1.当k=1的时候我们可以轻松解决。

当k>=2的时候我们尽量往k=1靠拢, 不断让k--, 我们可以把长度为n的 切成k段。 k段中的每一段取的点都是中位数所在的点。

2.===== ++++ --------------------- (k = 3)

然后我们就枚举最后一段--------------------------

3. dp[i][j]表示前i个数 分成j段的最优值。 f(left,right)表示 [left,right]中距离的最小值的和。

dp[i][j] = min(dp[i][j],dp[k][j-1] + f(k+1,i));

代码:

#include <cstring>
#include <stdio.h>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

int N,K;
const int maxn = 220;
const int maxk = 35;
int a[maxn];
int dp[maxn][maxk];

int f(int l,int r) {
int mid = (l + r) / 2;
int ret = 0;
for(int i=l;i<=r;i++) {
ret += abs(a[i] - a[mid]);
}
return ret;
}

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