选择原料工厂
来源:互联网 发布:中关村人工智能活动季 编辑:程序博客网 时间:2024/04/20 04:16
12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、31、38、39、47.在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,问应该选哪三个厂?
分析:
1、是一维问题,不是二维,可以抽象成:有12个点分布在一维坐标轴上,选择3个点,使得剩余的点到最近的点的距离之和最小。
2、工厂距离是从小到大排序的。
3、从N个工厂中选择1个原料厂,选择位于中位数位置的工厂,距离之和最短。
4、设A[i][j]表示从前i个工厂选择j个原料厂的最短距离,B[i][j]表示从第i个工厂到第j个工厂选择1个原料厂的最短距离。
对B[i][j]而言,1<=i<=j<=N
对A[i][j]而言,1<=j<=i<=N
从前i个工厂选择j个原料厂,可分为两部分:从前k个工厂选择j-1个原料厂和从第k+1个工厂到第i个工厂选择1个原料厂
i, j, k满足的条件为:1<=j-1<=k<i, k+1<=i
即,2<=j<=i, j-1<=k<=i
为什么j-1要大于等于1呢?若j-1等于0, 则前k个工厂没有原料厂了。
所以,递归解为:
A[i][j] = B[1][i], 即j=1时
A[i][j] = min{ A[k][j-1] + B[k+1][i] },其中2<=j<=i, j-1<=k<=i
源程序:
// 12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、 31、38、39、47.// 在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,问应该选哪三个厂?// 参数:// array: 工厂距离数组,array[1...n]为有效值,array[0]置0// length: 有效元素数目// 求从第begin个工厂到第end个工厂设1个原料厂的最短距离// 1<=begin<=end<=nstatic int min_distance(int *array, int begin, int end){ int mid = begin + (end - begin) / 2; int distance = 0; for (int i = begin; i <= end; ++i) { distance += abs(array[i]-array[mid]); } return distance;}// 输出从前i个工厂选择的j个原料厂static void print_selected_factory(const multi_array<int, 2> &opt, int length, int i, int j){ if (i <= j) { for (int k = 1; k <= i; ++k) { cout << k << " "; } return; } int k = opt[i][j]; print_selected_factory(opt, length, k, j-1); cout << k+1 + (i-k-1)/2 << " ";}int min_sum_of_distance(int *array, int length, int number){ if (array == NULL || length < 1) return 0; // min_distance_1[i][j]表示从第i个工厂到第j个工厂设1个原料厂的最短距离 multi_array<int, 2> min_distance_1(extents[length+1][length+1]); for (int i = 0; i <= length; ++i) min_distance_1[i][0] = 0; for (int j = 1; j <= length; ++j) min_distance_1[0][j] = 0; for (int i = 1; i <= length; ++i) for (int j = i; j <= length; ++j) min_distance_1[i][j] = min_distance(array, i, j); // min_distance_m[i][j]表示从前i个工厂中设j个原料厂的最短距离之和 multi_array<int, 2> min_distance_m(extents[length+1][length+1]); multi_array<int, 2> opt(extents[length+1][length+1]); for (int i = 0; i <= length; ++i) min_distance_m[i][0] = 0; for (int j = 1; j <= length; ++j) min_distance_m[0][j] = 0; for (int i = 1; i <= length; ++i) { int j = 1; min_distance_m[i][j] = min_distance_1[1][i]; for (j = 2; j <= i; ++j) { min_distance_m[i][j] = INT_MAX; for (int k = max(1, j-1); k < i; ++k) { int tmp = min_distance_m[k][j-1] + min_distance_1[k+1][i]; if (tmp < min_distance_m[i][j]) { min_distance_m[i][j] = tmp; opt[i][j] = k; } } } } cout << "min distance: " << min_distance_m[length][number] << endl; print_selected_factory(opt, length, length, number); cout << endl; return min_distance_m[length][number];}int main(int argc, char **argv){ int array[] = {0, 0, 4, 5, 10, 12, 18, 27, 30, 31, 38, 39, 47}; int length = sizeof(array) / sizeof(int); min_sum_of_distance(array, length-1, 3); return 0;}
参考:
http://blog.csdn.net/julianxiong/article/details/7381214
- 选择原料工厂
- 动态规划:选择原料工厂
- [经典面试题][腾讯]选择原料工厂(最短距离问题)
- [php]选择工厂和更新工厂模式
- 原料涨价,危机?机会?
- 第三章 原料加工
- 选择实现—简单工厂
- 三种工厂模式的使用选择
- ERP制成品成本计算整理(直接原料)
- 东南亚陶瓷等非金属矿产原料分布
- 膜结构停车棚采用的什么原料
- 原料行业用网络营销软件效果好吗?
- 第3章 加工原料文本
- 3.NLTK之加工原料文本
- 运用简单工厂实现登陆权限的选择
- [双语阅读]经济危机致原料短缺 古巴厕纸告急
- 为什么核电站的核反应堆原料一定要用铀?
- 以大便为原料的食品添加剂工艺流程开发
- CXF—六天系列—第五天—CXF+Spring配置客户端--HelloWorld!
- CXF—六天系列—第六天—找不到MessageFactoryImpl和BouncyCastleProvider类报错
- 【IAR】Error[Li005] no definition for "__program_start"
- hdu1595
- Android模拟器学framework和driver之battery & backlight-----5. backlight in linux
- 选择原料工厂
- 监视和截获指定进程网络数据传输WSockExpert0.6 工具介绍和使用实例
- hdoj1114
- Unity 官方网站
- 基本文件操作:NSFileHandle的用法
- [java]字符串的拼接问题
- linux下vi命令大全
- Android中使单选项列表框默认选中前次保存的值(即setSingleChoiceItems方法的使用)
- C++学习笔记之文件和流