趣味算法之怎样订饭最省钱

来源:互联网 发布:js点击一个按钮隐藏 编辑:程序博客网 时间:2024/05/01 23:27

近来很多同事都在网上订餐,网上订餐基本都会有优惠,不同家的优惠策略不同,但大体上都是三种策略,比如有几家是满15减6,满30减15,满50减20。

然后我突发奇想,何不写个程序,来根据餐厅的优惠政策计算下怎样拼饭最省钱呢?于是有了下面代码:

import java.util.ArrayList;import java.util.Scanner;public class Lunch {public static double[] Fee = {15, 30, 50};//满多少钱可优惠public static double[] Dis = {6, 15, 20};//对应的优惠价格public static double[] disCount;//折扣public static int[] strategy;//策略public static int[] price;//每份饭的单价public static int[] priceCopy;//同样是每份饭的单价public static double sumPrice = 0.0;//优惠前的总价public static int person = 0;//共几人订餐public static void main(String[] args) {Scanner sc = new Scanner(System.in);person = sc.nextInt();price = new int[person];priceCopy = new int[person];for(int i=0; i<person; i++){price[i] = sc.nextInt();priceCopy[i] = price[i];sumPrice += price[i];}disCount = new double[3];strategy = new int[3];    for(int i=0; i<3; i++){    disCount[i] = Dis[i]/Fee[i];    }double max = 0.0;int maxIndex = 0;for(int i=0; i<3; i++){max = disCount[i];maxIndex = i;for(int j=0; j<3; j++){if(disCount[j] > max){max = disCount[j];maxIndex = j;}}strategy[i] = maxIndex;disCount[maxIndex] = 0;}double save = cal();System.out.println("总共省钱"+save+"元");sc.close();}/** * 返回节约的饭钱 * straNum 是指当前使用的打折策略的编号 * save 是指已经节省的钱 * */private static double cal() {double save = 0.0;int straNum = 0;ArrayList<Integer> choosed = new ArrayList<Integer>();while(straNum < 3){int index = strategy[straNum];double pinPrice = Fee[index];if(sumPrice < pinPrice){straNum++;continue;}choosed = new ArrayList<Integer>();for(int add=0; true; add++){if(sumPrice < pinPrice + add){straNum++;break;}if(choose(pinPrice+add, 0, choosed)){sumPrice -= (pinPrice+add);save += Dis[index];System.out.println("此单凑出的钱数为:"+(pinPrice+add));System.out.print("由以下价格凑出:");for(int c:choosed){System.out.print(priceCopy[c]+" ");}System.out.println();break;}else{int nextIndex = strategy[straNum+1];double nextFee = Fee[nextIndex];double nextDis = Dis[nextIndex];int counts = (int) (((pinPrice+add)/nextFee)%1);double nextSave = nextDis * counts;if(nextSave > Dis[index]){straNum++;break;}}}}return save;}/** * 返回是否能拼出饭钱pinPrice * @param pinPrice 要拼的饭钱 *        cur 当前要处理的餐费 *        choosed 存放被选择的餐费的下标 * */private static boolean choose(double pinPrice, int cur, ArrayList<Integer> choosed){if(pinPrice < 0)return false;while(cur<person && price[cur]==0){cur++;}if(cur == person && pinPrice!=0)return false;if(pinPrice ==0 ){return true;}if(choose(pinPrice - price[cur], cur+1, choosed)){choosed.add(cur);price[cur] = 0;return true;}else if(choose(pinPrice, cur+1, choosed)){return true;}else{return false;}}}


0 0