为了账号安全,请及时绑定邮箱和手机立即绑定

Java数据结构算法问题,求最优解

Java数据结构算法问题,求最优解

守着一只汪 2018-07-13 10:18:32
实际开发中需要解决的问题,我在这里简化成简单的Map: Map<String,Integer> map=new HashMap<String,Integer>();  map.put("tom",78);  map.put("jerry",42);  map.put("marry",12);  map.put("hugh",37);  map.put("aaron",23);  map.put("john",40);  map.put("adam",67);  map.put("white",43);  map.put("chris",13);有这样一个map,key是名字,value是每个人拥有的钱有一件物品是240元,需要所有人一起凑钱购买,求最优解:1、第一优先的是人数,凑够钱买物品的人的组合里,人数最少的2、第二优先的是价格,要求超过240,但是离240最接近的一组,因为从大到小排列一定能得到人数最少的,但是可能会比目标数额大很多,导致找零太多最后要求返回满足上面两个条件的最优解,也就是这个组合里的所有元素
查看完整描述

1 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

    public static List<Integer> limitValSubsequence(int[] sequence, int limitValue) {
        List<Integer> retList = new ArrayList<>();

        int[] sortSeq = Arrays.copyOf(sequence, sequence.length);
        Arrays.sort(sortSeq);

        int sumVal = 0;
        int k = 0;
        for (int i = sortSeq.length - 1; i >= 0; i--) {
            sumVal += sortSeq[i];
            if (sumVal > limitValue) {
                k = sortSeq.length - i;
                break;
            }
        }
        if (k == 0) {
            System.err.println("No subsequence math condition to > " + limitValue);
            return retList;
        }

        limitValSubsequencePart(sortSeq, k, sequence.length - 1, limitValue, retList);
        return retList;
    }

        public static int limitValSubsequencePart(int[] sequence, int count, int right, int limitValue,
            List<Integer> outSeq) 
    {
        outSeq.clear();
        if (count <= 0) return Integer.MIN_VALUE;       //不可选了
        if (right < 0) return Integer.MIN_VALUE;
        int curVal = sequence[right];
        if (limitValue > count * curVal) return Integer.MIN_VALUE;

        if (right == 0) {
            if (curVal > limitValue && count == 1) {
                outSeq.add(curVal);
                return curVal;
            } else {
                return Integer.MIN_VALUE;
            }
        }

        //if curVal in
        List<Integer> curInSeq = new ArrayList<>();
        int inValue = Integer.MIN_VALUE;    //预设无效
        if (curVal > limitValue && count == 1) {
            inValue = curVal;
            curInSeq.add(curVal);
        } else {
            List<Integer> inSubSeq = new ArrayList<>();
            int subVal = limitValSubsequencePart(sequence, count - 1, right-1, limitValue - curVal, inSubSeq);
            if (subVal == Integer.MIN_VALUE) {//无效
                inValue = Integer.MIN_VALUE;
            } else {
                inValue = curVal + subVal;
                curInSeq.addAll(inSubSeq);
                curInSeq.add(curVal);
            }
        }

        //if curVal not in
        List<Integer> curOutSeq = new ArrayList<>();
        int outValue = limitValSubsequencePart(sequence, count, right-1, limitValue, curOutSeq);

        if (inValue == Integer.MIN_VALUE) {
            outSeq.addAll(curOutSeq);
            return outValue;
        } else if (outValue == Integer.MIN_VALUE) {
            outSeq.addAll(curInSeq);
            return inValue;
        } else {
            if (curInSeq.size() < curOutSeq.size()) {
                outSeq.addAll(curInSeq);
                return inValue;
            } else if (curInSeq.size() > curOutSeq.size()) {
                outSeq.addAll(curOutSeq);
                return outValue;
            } else {
                if (inValue > outValue) {
                    outSeq.addAll(curOutSeq);
                    return outValue;
                } else {
                    outSeq.addAll(curInSeq);
                    return inValue;
                }
            }
        }
    }  

  public static void testLimitValArray() {
    final int NUMBER = 150;
    int[] inputs = new int[NUMBER];
    for (int i = 0; i < NUMBER; i++) inputs[i] = i+1;
    int limitValue = NUMBER * 10;
    long startTime = System.currentTimeMillis();
    List<Integer> vals = limitValSubsequence(inputs,  limitValue);
    int sumVal = 0;
    for (int val : vals) sumVal += val;
    long usedTime = System.currentTimeMillis() - startTime;
    System.out.println("testLimitValArray limit:" + limitValue +  ", sum:" + sumVal + ", elems:" + vals + ", usedTime:" + usedTime);
  }


testLimitValArray limit:1500, sum:1501, elems:[46, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150], usedTime:9565


查看完整回答
反对 回复 2018-08-05
  • 1 回答
  • 0 关注
  • 882 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号