滴滴打车2017招聘笔试题

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

有个一个饭店,有n张桌子,每张桌子可以招待不同数量的客人,且不能拼桌,现在来了m批客人,每批客人有两个属性,一个是客人的总数,一个是他们消费(预计)的总额

请设计一个算法,计算出,店家能够获得的最大利润


我自己设计了一个算法,是这么思考的,先把客人排序,按照消费比(就是消费的金额除以人数)排序,然后吧桌子也排序

首先安排消费比最高的客人,从最小的桌子开始安排,如果桌子太小了,就换一个比它大一点的桌子

代码如下:


扫描二维码关注公众号,回复: 4859851 查看本文章

import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Scanner;class Table2 implements Comparable<Table2>int m; boolean used; int fee; public Table2(int count){  m=count; } @Override public int compareTo(Table2 o) {  if (o.m>=m) {   return -1;  }else {   return 1;  }   }}class Person implements Comparable<Person>int count; int fee; double rate; boolean zhaodai; public void computeRate(){  rate=fee*1.0/count; } public Person(int count,int fee){  this.count=count;  this.fee=fee; } @Override public int compareTo(Person o) {  if (o.rate>=rate) {   return 1;  }else {   return -1;  } } public String toString(){  return count+" "+" "+fee+" "+rate; }}public class Main public static void main(String[] args) {  int n,m;    Scanner sc=new Scanner(System.in);  n=sc.nextInt();  m=sc.nextInt();    List<Table2> nList=new ArrayList<>();  for (int i = 0; i < n; i++) {   Table2 table=new Table2(sc.nextInt());   nList.add(table);  }  Collections.sort(nList);  List<Person> pList=new ArrayList<>();  for (int i = 0; i < m; i++) {   Person person=new Person(sc.nextInt(),sc.nextInt());   person.computeRate();   pList.add(person);  }    Collections.sort(pList);//  for (int i = 0; i < pList.size(); i++) {//   System.out.println(pList.get(i));//  }    for (int i = 0; i < pList.size(); i++) {   Person person=pList.get(i);   if (!person.zhaodai) {    for (int j = 0; j < nList.size(); j++) {          Table2 t=nList.get(j);     if (!t.used) {      if (person.count<t.m) {       t.used=true;       t.fee=person.fee;       person.zhaodai=true;       break;      }     }         }   }  }  int sum=0;  for (int j = 0; j < nList.size(); j++) {   Table2 t=nList.get(j);   sum+=t.fee;  }  System.out.println(sum);     }}/*3 52 4 21 33 53 75 9 1 10    */
上面的测试用例

3 5代表一共有3个桌子 5批客人

2 4 2 代表3张桌子的容量 分别是2 4 2

后面的1 3 代表第一批客人是1个人 消费3元 然后是第二批客人,共3人消费5元

这个测试用例 最后的答案是20


这个思路,是很直观的,但是,我没办法判断它的正确性

其实它是错的

输入:
1 2
4
2 4
3 5
输出:
4
可答案应该是5才对,因为题目要求的是总消费最高

感谢网友yg33717 



后来,西安交大的张晨同学说,咱们用递归试试

思想就是 我随意让一个客人占用一张桌子(当然,至少客人得坐得下)计算一下收益率,然后把剩下的人和剩下的桌子递归调用安排的代码,就OK

我和我的小伙伴们都惊呆了,还能这么写

然后 过了20分钟,他给我发来这个下面的代码

import java.util.ArrayList;import java.util.Scanner;/** * Created by zhangchen([email protected]) on 2016/9/7. */public class TableGuest public static void main(String[] args) {  Scanner scanner = new Scanner(System.in);  int tableCount = 0;  int groupCount = 0;  while (scanner.hasNextLine()) {   tableCount = scanner.nextInt();   groupCount = scanner.nextInt();   ArrayList<Table> tables = new ArrayList<>();   ArrayList<GuestGroup> groups = new ArrayList<>();   for (int i = 0; i < tableCount; i++) {    tables.add(new Table(scanner.nextInt()));   }   for (int j = 0; j < groupCount; j++) {    groups.add(new GuestGroup(scanner.nextInt(), scanner.nextInt()));   }   int maxMoney = getMaxMoney(tables, groups);   System.out.println(maxMoney);  } } public static int getMaxMoney(ArrayList<Table> tables,   ArrayList<GuestGroup> groups) {  boolean[] isTableEmpty = new boolean[tables.size()];  boolean[] isGroupWait = new boolean[groups.size()];  for (int i = 0; i < isTableEmpty.length; i++) {   isTableEmpty[i] = true;  }  for (int j = 0; j < isGroupWait.length; j++) {   isGroupWait[j] = true;  }  int maxMoney = assignTable(tables, groups, isTableEmpty, isGroupWait,    tables.size(), groups.size());  return maxMoney; } public static int assignTable(ArrayList<Table> tables,   ArrayList<GuestGroup> groups, boolean[] isTableEmpty,   boolean[] isGroupWait, int tableLeft, int groupLeft) {  if (tableLeft == 0 || groupLeft == 0) {   return 0;  }  int[][] values = new int[tables.size()][groups.size()];// 第i行j列表示将table                // i分配给group j                // 产生的价值  for (int i = 0; i < tables.size(); i++) {   for (int j = 0; j < groups.size(); j++) {    Table table = tables.get(i);    GuestGroup group = groups.get(j);    if (isTableEmpty[i] && isGroupWait[j]      && table.getCapacity() >= group.getGuestCount()) { // 可以尝试分配     boolean[] isTableEmptyCurrent = isTableEmpty.clone();     boolean[] isGroupWaitCurrent = isGroupWait.clone();     isTableEmptyCurrent[i] = false;     isGroupWaitCurrent[j] = false;     values[i][j] = group.getMoney()       + assignTable(tables, groups, isTableEmptyCurrent,         isGroupWaitCurrent, tableLeft - 1,         groupLeft - 1);    }   }  }  int maxMoney = 0;  for (int i = 0; i < tables.size(); i++) {   for (int j = 0; j < groups.size(); j++) {    if (values[i][j] > maxMoney) {     maxMoney = values[i][j];    }   }  }  return maxMoney; }}class Table public Table(int capacity) {  this.capacity = capacity; } public int getCapacity() {  return capacity; } public void setCapacity(int capacity) {  this.capacity = capacity; } private int capacity;}class GuestGroup public GuestGroup(int guestCount, int money) {  this.money = money;  this.guestCount = guestCount; } private int guestCount; private int money; public int getGuestCount() {  return guestCount; } public void setGuestCount(int guestCount) {  this.guestCount = guestCount; } public int getMoney() {  return money; }}


过了一会,他又说,伙计,伙计,我又有了新的想法,

有一个二维矩阵,m[i][j]=k表示第i这个桌子招待第j批客人,获得的收益是k元

然后,这个矩阵的每一行,每一列都只能选一个元素

最后求最大值

他问我:你不觉得这代码,很熟悉么?

我看了看,恩,感觉有点像八皇后问题,对呀,他把所有符合规则的排练都求出来,找出最大的 不就OK了么

子曰:子曰:不愤不启,不悱不发.举一隅不与三隅反,则不复也

张晨自己能把这个问题联系到八皇后上,牛逼呀

贤哉,晨也!

代码如下:


import java.util.ArrayList;import java.util.HashMap;import java.util.Map.Entry;import java.util.Scanner;/** * Created by zhangchen([email protected]) on 2016/9/7. */public class TableGuest2 {    public static void main(String[] args){        Scanner scanner=new Scanner(System.in);        int tableCount=0;        int groupCount=0;        while(scanner.hasNextLine()){            tableCount=scanner.nextInt();            groupCount=scanner.nextInt();            ArrayList<Table> tables=new ArrayList<>();            ArrayList<GuestGroup> groups=new ArrayList<>();            for(int i=0;i<tableCount;i++){                tables.add(new Table(scanner.nextInt()));            }            for(int j=0;j<groupCount;j++){                groups.add(new GuestGroup(scanner.nextInt(),scanner.nextInt()));            }            int[][] assignmentMatrix=new int[tables.size()][groups.size()];            //将问题转化为在一个矩阵中,每行选择一个元素,这些元素不能在同一列,使得和最大            for(int i=0;i<tables.size();i++){                for(int j=0;j<groups.size();j++){                    Table table=tables.get(i);                    GuestGroup group=groups.get(j);                    if(table.getCapacity() >= group.getGuestCount()){                        assignmentMatrix[i][j] = group.getMoney(); //可以获利                    }else { //不能分配                        assignmentMatrix[i][j]=0;                    }                }            }//            int maxMoney= getMaxMoney(tables, groups);            int maxMoney= getMaxMoney(assignmentMatrix);            System.out.println(maxMoney);        }    }    public static int getMaxMoney(ArrayList<Table> tables, ArrayList<GuestGroup> groups){        boolean[] isTableEmpty=new boolean[tables.size()];        boolean[] isGroupWait=new boolean[groups.size()];        for(int i=0;i<isTableEmpty.length;i++){            isTableEmpty[i]=true;        }        for(int j=0;j<isGroupWait.length;j++){            isGroupWait[j]=true;        }        HashMap<Integer,Integer> bestAssignment=assignTable(tables,groups,isTableEmpty,isGroupWait,tables.size(),groups.size());        for(Entry<Integer,Integer> assign:bestAssignment.entrySet()){            System.out.println("将第"+assign.getKey()+"桌分配给"+assign.getValue()+"组客户");        }        return calculateMoney(groups,bestAssignment);    }    public static int getMaxMoney(int[][] assignmengMatrix){        int rowCount=assignmengMatrix.length;        int colCount=assignmengMatrix[0].length;        ArrayList<int[]> results=new ArrayList<>();        assignTable(0,new int[rowCount],rowCount,colCount,results);        int maxMoney=0;        int[] bestAssignment = new int[rowCount];        for(int[] columns:results){            int total=0;            for(int row=0;row<rowCount;row++){                total+=assignmengMatrix[row][columns[row]];            }            if(total>maxMoney){                maxMoney=total;                bestAssignment=columns;            }        }        for(int i=0;i<bestAssignment.length;i++){            System.out.println("将第"+i+"桌分配给"+bestAssignment[i]+"组客户");        }        return maxMoney;    }    public static void assignTable(int row,int[] columns,int rowCount,int colCount,ArrayList<int[]> results){        if(row == rowCount){//找到有效的分配方案            results.add(columns.clone());        }else{            for(int col=0;col<colCount;col++){                if(checkValid(columns,row,col)){ //分配是否有效                    columns[row]=col; //分配桌子                    assignTable(row+1,columns,rowCount,colCount,results);                }            }        }    }    public static boolean checkValid(int[] columns,int row1,int col1){        for(int row2=0;row2<row1;row2++){            int col2=columns[row2];            if(col2==col1){ //某一组客户被重复分配                return false;            }        }        return true;    }    public static HashMap<Integer,Integer> assignTable(ArrayList<Table> tables, ArrayList<GuestGroup> groups,boolean[] isTableEmpty,boolean[] isGroupWait,int tableLeft,int groupLeft){        HashMap<Integer,Integer> bestAssignment=new HashMap<>();        if(tableLeft==0 || groupLeft ==0 ){            return bestAssignment;        }        int maxMoney=0;        for(int i=0;i<tables.size();i++){            for(int j=0;j<groups.size();j++){                Table table=tables.get(i);                GuestGroup group=groups.get(j);                if(isTableEmpty[i] && isGroupWait[j] && table.getCapacity()>=group.getGuestCount()){ //可以尝试分配                    boolean[] isTableEmptyCurrent=isTableEmpty.clone();                    boolean[] isGroupWaitCurrent=isGroupWait.clone();                    isTableEmptyCurrent[i]=false;                    isGroupWaitCurrent[j]=false;                    HashMap<Integer,Integer> assighment=assignTable(tables, groups, isTableEmptyCurrent, isGroupWaitCurrent,tableLeft-1,groupLeft-1);                    assighment.put(i,j);                    int money=calculateMoney(groups,assighment);                    if(money>maxMoney){                        bestAssignment=assighment;                        maxMoney=money;                    }                }            }        }        return bestAssignment;    }    public static int calculateMoney(ArrayList<GuestGroup> groups,HashMap<Integer,Integer> assignment){        int total=0;        for(int groupIndex:assignment.values()){            total+=groups.get(groupIndex).getMoney();        }        return total;    }}


///////////////////////////////
以下为2016-9-14日补充
感谢"麦尔"对我文章的研究:
非常简单的问题,怎么搞得这么复杂,说明你的算法功底还很弱,继续加油学习哦,去TopCoder刷刷题

这个题如果你想到按个人消费排序你就完了,它要的收益最大,不在乎让最多的人就餐。
算法思路:
1.将总消费让从大到小排序 -- consume[m]
2.将桌子按容纳人数从小到大排序 -- capacity[n]
3.遍历consume[m],取出元素后,再从capacity[n]中找到大于或等于该元素人数的桌子,并在capacity[n]标记该桌已用,若没有桌子能容纳该批客则直接放弃该批客人。

就这么简单,考虑的是盈利最大,不是要考虑让更多的人就餐
最后想说我是一个三本学生...
哎怎么说呢,感觉读书把自己读傻了,这个问题本来就很生活化,回家问我不懂计算机的老妈,她估计都能想到这个方法,
我们这些研究生生却想到那么复杂的解法,真是读书读傻了,这是智商问题呀
以上为2016-9-14日补充
///////////////////////////////




           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_43678748/article/details/84071578