工厂分布距离最短
2015-03-02 10:05
141 查看
1.12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、 31、38、39、47.在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短, 问应该选哪三个厂 ?【问题来源于v_JULY_v的博客:/article/1360514.html】
第一部分:思路
1. 工厂是按照距离从小到大排序好的
2. 在N个工厂中选出1个原材料供应厂,则选取中位数所在的工厂,距离是最短的
3. 设A(i,j)表示前i个工厂选取j个原料供应厂的最短距离,B(m,n)表示从第m个工厂到第n个工厂选取1个原材料供应厂的最短距离。则有如下推导式:
A(i,j) = Min { A(t,j-1) + B(t+1,i) } 1<=t<i, t>=j-1
第二部分:Java代码,不考虑异常情况
[java] view
plaincopy
/**
* 12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、
* 31、38、39、47.在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,
* 问应该选哪三个厂 ?
* @param factory
* 每个工厂离公路最西端的距离
* @param len
* 工厂的数量
* @param number
* 原材料工供应厂的数量
* @return
* 返回1个number+1的数组,数组第1项为最短距离,余下number项为原材料供应厂
*/
public static int[] select(int[] factory, int len, int number)
{
int[][] former = new int[len][number+1],
latter = new int[len][number+1], tmp = null;
//初始化
for(int p=0;p<len;p++)
{
former[p][0] = distance(factory, 0, p);
former[p][1] = factory[p>>1];
}
//动态规划
for(int j=2;j<=number;j++)
{
for(int i=0;i<len;i++)
{
if(i+1<j) //工厂的数量少于原材料供应厂
{
continue;
}else
{
latter[i][0] = Integer.MAX_VALUE;
for(int t=i-1;t>=0;t--)
{
if(t+1<j-1) //工厂的数量少于原材料供应厂
{
continue;
}else
{
int curDis = former[t][0] + distance(factory, t+1, i);
if(latter[i][0]>curDis)
{
latter[i][0] = curDis;
for(int m=1;m<=j-1;m++)
{
latter[i][m] = former[t][m];
}
latter[i][j] = factory[(t+1+i)>>1];
}
}
}
}
}
//交换
tmp = latter;
latter = former;
former = tmp;
}
return former[len-1];
}
/**
* 求从第m个工厂到第n个工厂设1个原料供应厂的最短距离
*/
static int distance(int[] factory, int left, int right)
{
int mid = (left+right)>>1;
int dis = 0;
for(int i=left;i<=right;i++)
{
int dif = factory[i]-factory[mid];
dis += ((dif>0)?dif:-1*dif);
}
return dis;
}
第三部分:测试用例
工厂:{0,4,5,10},选取1个原材料供应厂: {11,4},最短距离为11,选取4做原材料供应厂
工厂:{0,4,5,10},选取2个原材料供应厂: {5,4,10},最短距离为5,选取4,10做原材料供应厂
工厂:{0,4,5,10,12},选取2个原材料供应厂: {7,4,10},最短距离为7,选取4,10做原材料供应厂
工厂:{0,4,5,10,12},选取3个原材料供应厂: {3,0,4,10},最短距离为3,选取0,4,10做原材料供应厂
工厂:{0,4,5,10,12,18,27,30,31,38,39,47},选取3个原材料供应厂: {43,5,27,39},最短距离为43,选取5,27,39做原材料供应厂
第一部分:思路
1. 工厂是按照距离从小到大排序好的
2. 在N个工厂中选出1个原材料供应厂,则选取中位数所在的工厂,距离是最短的
3. 设A(i,j)表示前i个工厂选取j个原料供应厂的最短距离,B(m,n)表示从第m个工厂到第n个工厂选取1个原材料供应厂的最短距离。则有如下推导式:
A(i,j) = Min { A(t,j-1) + B(t+1,i) } 1<=t<i, t>=j-1
第二部分:Java代码,不考虑异常情况
[java] view
plaincopy
/**
* 12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、
* 31、38、39、47.在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,
* 问应该选哪三个厂 ?
* @param factory
* 每个工厂离公路最西端的距离
* @param len
* 工厂的数量
* @param number
* 原材料工供应厂的数量
* @return
* 返回1个number+1的数组,数组第1项为最短距离,余下number项为原材料供应厂
*/
public static int[] select(int[] factory, int len, int number)
{
int[][] former = new int[len][number+1],
latter = new int[len][number+1], tmp = null;
//初始化
for(int p=0;p<len;p++)
{
former[p][0] = distance(factory, 0, p);
former[p][1] = factory[p>>1];
}
//动态规划
for(int j=2;j<=number;j++)
{
for(int i=0;i<len;i++)
{
if(i+1<j) //工厂的数量少于原材料供应厂
{
continue;
}else
{
latter[i][0] = Integer.MAX_VALUE;
for(int t=i-1;t>=0;t--)
{
if(t+1<j-1) //工厂的数量少于原材料供应厂
{
continue;
}else
{
int curDis = former[t][0] + distance(factory, t+1, i);
if(latter[i][0]>curDis)
{
latter[i][0] = curDis;
for(int m=1;m<=j-1;m++)
{
latter[i][m] = former[t][m];
}
latter[i][j] = factory[(t+1+i)>>1];
}
}
}
}
}
//交换
tmp = latter;
latter = former;
former = tmp;
}
return former[len-1];
}
/**
* 求从第m个工厂到第n个工厂设1个原料供应厂的最短距离
*/
static int distance(int[] factory, int left, int right)
{
int mid = (left+right)>>1;
int dis = 0;
for(int i=left;i<=right;i++)
{
int dif = factory[i]-factory[mid];
dis += ((dif>0)?dif:-1*dif);
}
return dis;
}
第三部分:测试用例
工厂:{0,4,5,10},选取1个原材料供应厂: {11,4},最短距离为11,选取4做原材料供应厂
工厂:{0,4,5,10},选取2个原材料供应厂: {5,4,10},最短距离为5,选取4,10做原材料供应厂
工厂:{0,4,5,10,12},选取2个原材料供应厂: {7,4,10},最短距离为7,选取4,10做原材料供应厂
工厂:{0,4,5,10,12},选取3个原材料供应厂: {3,0,4,10},最短距离为3,选取0,4,10做原材料供应厂
工厂:{0,4,5,10,12,18,27,30,31,38,39,47},选取3个原材料供应厂: {43,5,27,39},最短距离为43,选取5,27,39做原材料供应厂
相关文章推荐
- [经典面试题][腾讯]选择原料工厂(最短距离问题)
- [经典面试题][腾讯]选择原料工厂(最短距离问题)
- 2.11寻找最近的点对 (给定一系列的点,求出距离最短的点对)
- 最短编辑距离
- 数据结构:点对之间最短距离--Floyd算法
- 任意两节点之间最短距离
- 给出两个单词,找到它们的最短距离 (以它们之间隔了多少个单词计数)。
- 两个单词之间的最短距离
- 图-一点点到其他点的最短距离
- 街区最短路径问题--所谓的曼哈顿距离,不是很懂
- 2083 简单版最短距离
- 两个字符串之间的最短编辑距离
- 蜂窝小区最短距离实现 (构造图+广度优先算法)
- poj 1724 有限制的最短距离(优先队列+链表)
- 蜂窝小区最短距离实现 (数学归纳法+广度优先算法)
- hdu 6097 Mindis(圆上一点到圆内(距圆心相等的)两点的距离和最短)
- 单源点最短距离(Dijkstra)
- HDOJ(HDU) 2083 简易版之最短距离(中位数)
- 简易版之最短距离
- 港口钓鱼 求人员分配 移动最短距离值和 三个门