前言
本码农每天地铁通勤上下班,按平均计算每月需要上班的工作日为22天,即需要刷地铁44次。
羊城通优惠如下
- 每月刷公交前15次按票价 95折 计算,最低票价为2元
- 每月刷公交满15次后按票价 6折 计算
- 每月优惠清零。即每个月都需要刷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
由此可得
- 差价与通勤次数X无关,差价由通勤单价Y 以及刷卡操作次数Z决定,当通勤单价Y满足条件 0.35Y-1.9 ≦ 0 时,即 Y ≦ 5.428元时,差价小于等于零。
- 当通勤单价高于5.428元时,低价先刷卡操作次数越多越好,即直接刷满15次即可。
方案B:当通勤次数 X ≦ 15 ,且 X > 15-Z 时 (略)
方案B:当通勤次数 X ≦ 15 ,且 X <= 15-Z 时 (略)
结论
- 通勤单价如果少于5.428元钱就不划算了,不用考虑
- 当通勤单价高于5.428元时,低价先刷卡操作次数越多越好,即直接刷满15次即可。
- 好吧~其实吧...也省不了多少钱,还是多搞几个Bug吧