[经典面试题][腾讯]选择原料工厂(最短距离问题)
来源:互联网 发布:南充58程序员 编辑:程序博客网 时间:2024/03/29 08:54
题目
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个原料厂的最短距离。(1<=i<=j<=N)
B[i][j]表示从第i个工厂到第j个工厂选择1个原料厂的最短距离。(1<=j<=i<=N)
从前i个工厂选择j个原料厂,可分为两部分:从前k个工厂选择j-1个原料厂和从第k+1个工厂到第i个工厂选择1个原料厂(1<=j-1<=k< i, k+1<=i)
所以,递归解为:
A[i][j] = B[1][i], 即j=1时
A[i][j] = min{ A[k][j-1] + B[k+1][i] },其中1<=j-1<=k< i, k+1<=i
代码
/*--------------------------------------------- * 日期:2015-03-02 * 作者:SJF0115 * 题目: 选择原料工厂(最短距离问题) * 来源:腾讯 盛大 * 博客: -----------------------------------------------*/ #include <iostream> #include <algorithm> #include <climits> #include <vector> #include <math.h> using namespace std; int fac[100][100]; // n工厂个数 count原料厂个数 result原料厂下标集合 vector<int> BestFactoryPoint(int n,int count){ vector<int> result; //[1,n] int k; for(int i = 1;i <= n;){ //[1,n]分成两部分[1,k]有count-1个原料厂[k+1,n]有1个原料厂 k = fac[n][count--]; // [k+1,n]有一个原料厂,中位点就是原料厂点 result.push_back(k+1 + (n-k-1)/2); // 所有原料厂寻找完毕 if(count == 0){ break; }//if // 如果工厂个数小于原料厂个数 // 所有工厂全是原料厂 if(k <= count){ for(int i = 1;i <= k;++i){ result.push_back(i); }//for break; }//if // 求[1,k]部分 n = k; }//for return result; } // 从[start,end]选择一点使其到其他点的距离最小 int MinDistanceOneFactory(int point[],int start,int end){ if(start > end){ return -1; }//if int mid = (start + end) / 2; // 计算距离 int distance = 0; for(int i = start;i <= end;++i){ distance += abs(point[i] - point[mid]); }//for return distance; } // int MinDistance(int point[],int n,int count){ if(n <= 0){ return -1; }//if // // B[i][j]表示从第i个工厂到第j个工厂设1个原料厂的最短距离 // i <= j B上三角有用 int B[n+1][n+1]; // 计算第i个工厂到第j个工厂设1个原料厂的最短距离 for(int i = 1;i <= n;++i){ for(int j = i;j <= n;++j){ B[i][j] = MinDistanceOneFactory(point,i,j); }//for }//for // A[i][j]表示从前i个工厂中设j个原料厂的最短距离之和 int A[n+1][n+1]; // i前i个工厂 for(int i = 1;i <= n;++i){ // 设j个原料厂 // j = 1时 A[i][1] = B[1][i]; for(int j = 2;j <= i;++j){ A[i][j] = INT_MAX; for(int k = j-1;k < i;++k){ int curMin = A[k][j-1] + B[k+1][i]; if(curMin < A[i][j]){ A[i][j] = curMin; fac[i][j] = k; }//if }//for }//for }//for return A[n][count]; } int main() { int array[] = {0, 0, 4, 5, 10, 12, 18, 27, 30, 31, 38, 39, 47}; int n = 12; int count = 3; cout<<"最小距离->"<<MinDistance(array,n,count)<<endl; vector<int> result = BestFactoryPoint(n,count); for(int i = result.size()-1;i >= 0;--i){ cout<<array[result[i]]<<" "; }//for cout<<endl; return 0; }
0 0
- [经典面试题][腾讯]选择原料工厂(最短距离问题)
- 选择原料工厂
- 腾讯经典面试题
- 动态规划:选择原料工厂
- 腾讯经典Android面试题
- 九章算法面试题30 最短距离和
- 腾讯公司后台服务器经典面试题
- 腾讯公司后台服务器经典面试题
- 腾讯公司后台服务器经典面试题
- 腾讯公司后台服务器经典面试题
- [经典面试题][腾讯]集合差集
- [经典面试题][腾讯]字符串匹配
- [经典面试题][腾讯]字符串匹配
- 一类最短距离问题
- 素数最短距离问题
- 字符串最短距离问题
- 腾讯QQ面试题:赛马问题
- 腾讯面试题(奶牛产子问题)
- IOS开发-第一个APP项目
- linux下修改文件的拥有者和用户组
- C# 冷门的语法和属性方法
- 亚像素类型的意义
- 巴菲特致股东的一封信:1991年
- [经典面试题][腾讯]选择原料工厂(最短距离问题)
- wince 下APP的背景
- MongoDB 2.6-Windows安装
- SVN版本管理
- android笔记--保存和恢复activity的状态数据
- Android特殊字体的处理---加下划线等
- iOS开发-多线程开发之线程安全篇
- 巴菲特致股东的一封信:1990年
- DBus 入门与应用--基本概念 上(C API 级别的使用观点)