编程之美--1.8--小飞的电梯调度问题--扩展问题--2--(M层电梯选择K层停靠)

一,分析:

M层电梯K个停靠层,可将最终问题分成两种情况:1,第M层为一个停靠层次;2,第M层不作为停靠层次。第一种情况通过动态规划解出,第二种情况运用第一种情况子问题数据可以解出。

二,解法:

用数组A[1]、A[2]、...A[M]分别记录需到电梯1~M层的乘客人数;Cost[i][j]记录i层到j层之间,只有第i和第j两层可以停靠,乘客(i和j层之间所有乘客)需要爬的电梯的最少层数;F[i][j]表示1~i层电梯之间,j个楼层停靠,且第i层必须是一个停靠层的的最优解;所求解为S[M][K],即电梯总共M个层,有K个停靠层,使所有乘客所有乘客需要爬的电梯层数最少,该选择哪些层停靠?最少是多少层?

状态方程为:

 S[i][j] = min{F[i][j],     min{F[i-t][j] + A[i]*t + A[i-1]*(t-1) + A[i-2]*(t-2)...A[i-t+1]*1}  (1 <= t <= i-j)   }  

        

       解释:最外层min{}中前一部分表示第i层作为停靠层的情况,后一部分表示第i层不作为停靠层的情况

三,参考代码

unsigned int min(unsigned int *pa,unsinged int *pb)

{

  return (*pa > *pb) ? *pb : *pa;

}

//i floor not being stay_floor
void i_not_stay(int i, int j, int *pstay, unsigned int *psum_min)
{
    if (!pstay || !psum_min)
        return ;
    unsigned int local_min_1 = 0xffffffff;
    int local_min_pos = -1;
    int t,p;
    for (t = 1; t < i - j; t++)    {
        unsigned int local_sum = 0;
        for (p = i; p >= i - t + 1; p--)    {
            local_sum + = A[p] * [p - (i - t)]
        }
        local_sum += F[i - t][j];
        if (local_sum < local_min_1) {
            local_min_1 = local_sum;
            local_min_pos = i - t;
        }
    }
    *psum_min = local_min_1;
    *pstay = local_min_pos;
}

//S[M][K]

unsigned int F[M]+1[K+1] = {0};

unsigned int Cost[M+1][K+1] = {0};

int  main()

{

     //Cost[i][j]:

     int i,j,t;
     for (i = 1; i < M; i++)    {
         for (j = i; j <= M;j++)    {
           Cost[i][j] = 0;
            if ((j - i + 1) % 2)    {
                Cost[i][j] = ((i + j)/2 - i) * A[(i + j) / 2];
                for (t = i; t < (i + j) / 2; t++)    {
                Cos[i][j] += (t - i) * A[t] * 2;
             }
         } else    {
             for (t = i; t <= (i + j) / 2; t++)    {
                 Cost[i][j] += (t - i) * A[t] * 2;
             }   
         }
     }
     //F[i][j]
     for (i = 1; i <=M; i++)  {
         for (j = i; j<= M; j++) {
             if (j == i)
                 F[i][j] = 0;
             if (i > 1 && j == 1) {
                 F[i][j] = F[i-1][1] + A[i-1];
             }

             int t;
             unsigned int local_min = 0xffffffff;
             for (t = 1; t <= i-j+1; t++) {
                 unsigned int  tmp = F[i - t][j - 1] + Cost[i - t][j];
                 if (tmp < local_min)
                     local_min = tmp;
             }
             F[i][j] = local_min;

         }

     }

     int stay_floor;

     unsigned int sum_min;

     i_not_stay(M, K, &stay_floor,  &sum_min);

     S[M][K] = min(&F[M][K],&sum_min);

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值