编程之美—小飞的电梯调度问题 (停k层的解法)
2010-09-20 18:46:25| 分类: 算法|举报|字号 订阅
问题.有一栋楼,一共有N层,要去每一层的人分别是A[1],A[2]….A[N],如果电梯可以停K次,问停在哪K层让所有人走的矩离最短?
[备注:这只是我的个人解法,欢迎和我讨论]
解法:
用一个数组opt[i][j]记录电梯前i次停在1到j层之间,所有人走的路的最短矩离。用cost[i][j]记录如果电梯从第i层到第j层只能停一次,电梯停在最佳位置让所有人走的矩离最短的最优解。那么cost[i][j]怎么求呢?(这里把这个解法省略,具体可参见编程之美“小飞的电梯调度”)。如果前i次停留在前j层,那么第i+1次停留在第j+1至j+k层(j+k<=n),则状态转移方程为
opt[i+1][j+k]=min{opt[i][j]+cost[j+1][j+k];} (k+j<=n)
Cost数组存放电梯从第i层到j层停一次的最小走动矩离,构造cost的代码如下:
for(i=1;i<=m;i++)
for(j=i;j<=m;j++)
{
cost[i][j] = 0;
mid = 求得电梯在i到j层的最佳停留位置;
for(k=i;k<=j;k++)
cost[i][j]+=(distance[mid]-distance[k])>=0 ?
distance[mid]-distance[k]:distance[k]-distance[mid];
}
Opt[i][j] 表示从电梯在第1层到第j层停i次所有人的最小走动矩离,对于i=1(即电梯只停一次的情况)来说,opt[i][j] = cost[i][j],如果让电梯在1 至 j层停两次,也就是i=2的情况,可能是下面一种情况的最优解:
第一次停在第一层,第二次停在2至j层;
第一次停在1至2层,第二次停在3至j层;
第一次停在1至3层,第二次停在4至j层;
等等。。。。。
该部分的代码如下:
for(i=0;i<=n;i++)
for(j=0;j<=m;j++)
if(opt[i][j]<Integer.max)
{
for(k=1;j+k<=m;k++)
{
if(opt[i+1][j+k]>opt[i][j]+cost[j+1][j+k])
{
opt[i+1][j+k] = opt[i][j]+cost[j+1][j+k];
}
}
}