• 羊城通薅羊毛6折公交算法


    前言

    本码农每天地铁通勤上下班,按平均计算每月需要上班的工作日为22天,即需要刷地铁44次。

    羊城通优惠如下

    1. 每月刷公交前15次按票价 95折 计算,最低票价为2元
    2. 每月刷公交满15次后按票价 6折 计算
    3. 每月优惠清零。即每个月都需要刷15次后才有6折优惠

    想法

    如果我每月初先按最低的 2元票价刷满15次 ,接下来上下班通勤就都有6折了,这样能不能省下点~.... [手动dog]

    开工...

    
    public class Main {
    
        public static void main(String[] args) {
            getMostEconomicalSolution(8, 16);
        }
    
        /**
         * 计算最低成本方案
         *
         * @param numberOfRidesRequired 通勤次数
         * @param normalFare            通勤票价
         * @return
         */
        private static Double getMostEconomicalSolution(Integer numberOfRidesRequired, Integer normalFare) {
            Integer bastCount = 0;
            Double bastFace = null;
            for (int i = 0; i <= 15; i++) {
                Double fare = operatingMetroFareCalculation(numberOfRidesRequired, normalFare, i);
                System.out.println("操作" + i + "次成本为" + fare);
    
                if (i == 0) {
                    bastFace = fare;
                } else {
                    if (fare < bastFace) {
                        bastFace = fare;
                        bastCount = i;
                    }
                }
            }
    
            Double normaTotal = normalMetroFareCalculation(numberOfRidesRequired, normalFare);
    
            if (bastFace < normaTotal) {
                System.out.println("最佳操作次数为:" + bastCount + "次,成本为:" + bastFace);
                System.out.println("原始成本为:" + normaTotal + ",可节约 " + (normaTotal - bastFace) + " 元。");
            } else {
                System.out.println("最佳操作次数为:0次,成本为:" + normaTotal);
                System.out.println("原始成本为:" + normaTotal + ",可节约 0 元。");
            }
            return bastFace;
        }
    
        /**
         * 计算先按最低票价2元刷次数以及通勤的总费用
         *
         * @param numberOfRidesRequired 通勤次数
         * @param normalFare            通勤票价
         * @param operatingCount        低价刷次数
         * @return
         */
        private static Double operatingMetroFareCalculation(Integer numberOfRidesRequired, Integer normalFare, Integer operatingCount) {
            if (operatingCount < 0 || operatingCount > 15) throw new RuntimeException("操作次数必须在0~15之间");
    
            if (numberOfRidesRequired > (15 - operatingCount)) {
                return operatingCount * 2 * 0.95
                        + (15 - operatingCount) * normalFare * 0.95
                        + normalFare * (numberOfRidesRequired - 15 + operatingCount) * 0.6;
            } else {
                return operatingCount * 2 * 0.95
                        + numberOfRidesRequired * normalFare * 0.95;
            }
        }
    
        /**
         * 计算正常通勤总费用
         *
         * @param numberOfRidesRequired 通勤次数
         * @param normalFare            通勤票价
         * @return
         */
        private static Double normalMetroFareCalculation(Integer numberOfRidesRequired, Integer normalFare) {
            if (numberOfRidesRequired > 15) {
                return 15 * normalFare * 0.95 + (numberOfRidesRequired - 15) * normalFare * 0.6;
            } else {
                return numberOfRidesRequired * normalFare * 0.95;
            }
        }
    }
    
    
    

    计算

    按44次通勤,票价5元计算

    按44次通勤,票价6元计算

    按44次通勤,票价7元计算

    按15次通勤,票价6元计算

    方程式

    设差价为N,通勤次数为X,通勤单价为Y,低价先刷卡操作次数为Z,
    设正常通勤总费用为O,操作后通勤总费用为P

    方案A:当通勤次数 X > 15 时,

    
    O=15×0.95Y+(X-15)×0.6Y=14.25Y+0.6XY-9Y=5.25Y+0.6XY ,
    
    P=2×0.95Z+(15-Z)×0.95Y+(X-(15-Z))×0.6Y=1.9Z+14.25Y-0.95ZY+0.6XY-9Y+0.6ZY=1.9Z+0.6XY+5.25Y-0.35ZY ,
    
    则 N=O-P
        =5.25Y+0.6XY-(1.9Z+0.6XY+5.25Y-0.35ZY)
        =0.35ZY-1.9Z
        =(0.35Y-1.9)×Z
    
    

    由此可得

    1. 差价与通勤次数X无关,差价由通勤单价Y 以及刷卡操作次数Z决定,当通勤单价Y满足条件 0.35Y-1.9 ≦ 0 时,即 Y ≦ 5.428元时,差价小于等于零。
    2. 当通勤单价高于5.428元时,低价先刷卡操作次数越多越好,即直接刷满15次即可。

    方案B:当通勤次数 X ≦ 15 ,且 X > 15-Z 时 (略)

    方案B:当通勤次数 X ≦ 15 ,且 X <= 15-Z 时 (略)

    结论

    1. 通勤单价如果少于5.428元钱就不划算了,不用考虑
    2. 当通勤单价高于5.428元时,低价先刷卡操作次数越多越好,即直接刷满15次即可。
    3. 好吧~其实吧...也省不了多少钱,还是多搞几个Bug吧
  • 相关阅读:
    OpenSSH服务——密钥登录
    进程管理
    磁盘管理
    文件系统
    shell命令手册
    第一次常用命令手册
    远程连接mobaxterm安装使用
    Linux 系统CentOS 7 64 位安装
    PythonI/O进阶学习笔记_11.python的多进程
    PythonI/O进阶学习笔记_10.python的多线程
  • 原文地址:https://www.cnblogs.com/eedc/p/13791977.html
Copyright © 2020-2023  润新知