司机调度问题

简介: 司机调度问题

题目

现有司机N*2人,调度中心会将所有司机平分给A、B两个区域
第 i 个司机去A可得收入为incomei,
第 i 个司机去B可得收入为incomei,
返回所有调度方案中能使所有司机总收入最高的方案,是多少钱

一、暴力递归

递归含义:index可以去A区或者B区,A区还剩rest个名额
递归basie key:
1)没有司机可以选,返回0,
2)A区名额已满,司机只能去B区
3)B区名额已满,司机只能去A去

    public static int maxMoney(int[][] income) {
        if (income == null || income.length < 2 || (income.length & 1) != 0) {
            return 0;
        }
        int N = income.length; // 司机数量一定是偶数,所以才能平分,A N /2 B N/2
        int M = N >> 1; // M = N / 2 要去A区域的人
        return process(income, 0, M);
    }

    // index.....所有的司机,往A和B区域分配!
    // A区域还有rest个名额!
    // 返回把index...司机,分配完,并且最终A和B区域同样多的情况下,index...这些司机,整体收入最大是多少!
    public static int process(int[][] income, int index, int rest) {
        if (index == income.length) {
            return 0;
        }
        // B区满了
        if (income.length - index == rest) {
            return income[index][0] + process(income, index + 1, rest - 1);
        }
        //A区满了
        if (rest == 0) {
            return income[index][1] + process(income, index + 1, rest);
        }
        // 当前司机,可以去A,或者去B
        int p1 = income[index][0] + process(income, index + 1, rest - 1);
        int p2 = income[index][1] + process(income, index + 1, rest);
        return Math.max(p1, p2);
    }

二、动态规划

dpi含义:有i个司机,A区还有j个名额,最大收入是多少
根据递归Basie Key:
递归

    if (income.length - index == rest) {
        return income[index][0] + process(income, index + 1, rest - 1);
    }

在dp中:

    if (N - i == j) {
        dp[i][j] = income[i][0] + dp[i + 1][j - 1];
    }

递归:

    if (rest == 0) {
        return income[index][1] + process(income, index + 1, rest);
    }

在dp中

    if (j == 0) {
        dp[i][j] = income[i][1] + dp[i + 1][j];
    }

总代码

    public static int maxMoney2(int[][] income) {
        int N = income.length;
        int M = N >> 1;
        int[][] dp = new int[N + 1][M + 1];
        for (int i = N - 1; i >= 0; i--) {
            for (int j = 0; j <= M; j++) {
                if (N - i == j) {
                    dp[i][j] = income[i][0] + dp[i + 1][j - 1];
                } else if (j == 0) {
                    dp[i][j] = income[i][1] + dp[i + 1][j];
                } else {
                    int p1 = income[i][0] + dp[i + 1][j - 1];
                    int p2 = income[i][1] + dp[i + 1][j];
                    dp[i][j] = Math.max(p1, p2);
                }
            }
        }
        return dp[0][M];
    }
相关文章
|
Java 调度
计及绿证交易及碳排放的含智能楼宇微网优化调度(Matlab代码实现)
计及绿证交易及碳排放的含智能楼宇微网优化调度(Matlab代码实现)
106 0
|
传感器 算法 数据挖掘
【VRP问题】基于企鹅优化算法求解冷链配送物流车辆调度优化研究(Matlab代码实现)
【VRP问题】基于企鹅优化算法求解冷链配送物流车辆调度优化研究(Matlab代码实现)
148 0
【VRP问题】基于企鹅优化算法求解冷链配送物流车辆调度优化研究(Matlab代码实现)
|
机器学习/深度学习 传感器 算法
【配送路径规划】基于模拟退火算法的无人机药品配送路线规划(条件:病人多且距离近优先)附Matlab代码
【配送路径规划】基于模拟退火算法的无人机药品配送路线规划(条件:病人多且距离近优先)附Matlab代码
|
传感器 算法 数据挖掘
【VRP问题】基于帝国企鹅优化算法求解冷链配送物流车辆调度优化研究
【VRP问题】基于帝国企鹅优化算法求解冷链配送物流车辆调度优化研究
149 0
|
机器学习/深度学习 传感器 算法
基于蚁群算法的多配送中心的车辆调度问题的研究附Matlab代码
基于蚁群算法的多配送中心的车辆调度问题的研究附Matlab代码
|
监控 安全 定位技术
第七期 | 网约车司机的“捞偏门”手段:作弊抢单、空跑刷单
顶象防御云业务安全情报中心监测到,多个网约车出行平台存在作弊软件抢单、空跑刷单等欺诈行为,不仅损害乘客利益,更严重影响平台正常运营。
519 0
第七期 | 网约车司机的“捞偏门”手段:作弊抢单、空跑刷单
【智力题】轮胎的寿命
有一种轮胎,放在一辆自行车的前轮能骑5000km,放在后轮因磨损大只能骑3000km。为延长使用寿命,可以骑过一段路程后,前后轮胎对换使用。问:采用这种方法,一辆自行车和两个这种轮胎最多能骑多少km?答案:3750km.分析:前轮换到后轮后,轮胎寿命(单位:km)变为原来3/5,反之5/3.设骑了x km后换轮胎。
998 0