题解 | #牛舍安排问题#
牛舍安排问题
https://www.nowcoder.com/practice/b56eb97b8b5941d3a14cd4ce7238f502
int calMinDistance(int* house, int housesLen, int index) {
int totalDistance = 0;
int median = (housesLen + index) / 2;
for (int i = index; i < housesLen; ++i) {
int distance = house[i] > house[median] ? house[i] - house[median] :
house[median] - house[i];
totalDistance += distance;
}
return totalDistance;
}
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param houses int整型一维数组
* @param housesLen int houses数组长度
* @param k int整型
* @return int整型
*/
int minTotalDistance(int* houses, int housesLen, int k) {
// 定义动态规划数组,dp[i][j]表示前i栋牛舍分配j个喂食区的情况下,
// 前i栋牛舍离最近的喂食区之前的距离总和最小值
int** dp = (int**)malloc(sizeof(int*) * (housesLen + 1));
for (int i = 0; i < housesLen + 1; ++i) {
dp[i] = (int*)malloc(sizeof(int) * (k + 1));
}
// 处理边界值,若牛舍数量为0,则无论分配多少个喂食区,距离之和都是0
for (int j = 0; j < k + 1; ++j) {
dp[0][j] = 0;
}
// 定义初始值,只要牛舍数量不为0,那么默认距离之和为最大值
for (int i = 1; i < housesLen + 1; ++i) {
for (int j = 0; j < k + 1; ++j) {
dp[i][j] = 2147483627;
}
}
// 遍历处理,i代表前i栋牛舍
for (int i = 1; i < housesLen + 1; ++i) {
// j代表分配j个喂食区
for (int j = 1; j < k + 1; ++j) {
// m表示把前m个牛舍分配j-1个喂食区,
// 剩下的i-m个牛舍分配1个喂食区
for (int m = 0; m < i; ++m) {
if (dp[m][j - 1] == 2147483627) continue;
if (dp[i][j] > dp[m][j - 1] + calMinDistance(houses, i, m)) {
dp[i][j] = dp[m][j - 1] + calMinDistance(houses, i, m);
}
}
}
}
int result = dp[housesLen][k];
for (int i = 0; i < housesLen + 1; ++i) {
free(dp[i]);
}
free(dp);
return result;
}
