動態規劃-hdu1227Fast Food

題意:

從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[N][K]);
	}
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章