zoukankan      html  css  js  c++  java
  • 算法与数据结构-最小化舍入误差以满足目标

    最小化舍入误差以满足目标

    题目

    leetcode原题:1058. 最小化舍入误差以满足目标

    给定一系列价格 [p1,p2...,pn] 和一个目标 target,将每个价格 pi 舍入为 Roundi(pi) 以使得舍入数组 [Round1(p1),Round2(p2)...,Roundn(pn)] 之和达到给定的目标值 target。每次舍入操作 Roundi(pi) 可以是向下舍 Floor(pi) 也可以是向上入 Ceil(pi)。

    如果舍入数组之和无论如何都无法达到目标值 target,就返回 -1。否则,以保留到小数点后三位的字符串格式返回最小的舍入误差,其定义为 Σ |Roundi(pi) - (pi)|( i 从 1 到 n )。

    示例 1:

    输入:prices = ["0.700","2.800","4.900"], target = 8
    输出:"1.000"
    解释:
    使用 Floor,Ceil 和 Ceil 操作得到 (0.7 - 0) + (3 - 2.8) + (5 - 4.9) = 0.7 + 0.2 + 0.1 = 1.0 。

    示例 2:

    输入:prices = ["1.500","2.500","3.500"], target = 10
    输出:"-1"
    解释:
    达到目标是不可能的。

    解析

    这道题的核心需要思考出:

    • 所有数据向上取整的整数和sumFloor-target的相差个数就是 结果中 ceil的个数

    • 所有数据向下取整的整数和sumCeil-target的相差个数就是 结果中 floor的个数

    已知满足条件的解中的ceil和floor的个数,并且需要求最小误差和,那就分别正序排序floor和ceil的误差list

    按照floor和ceil的个数相加得到总和即可!

    代码

    import java.math.BigDecimal;
    class Solution {
        public String minimizeError(String[] prices, int target) {
           //生成相关待使用数据
           List<BigDecimal> floorList = new ArrayList<>(prices.length);
           List<BigDecimal> ceilList = new ArrayList<>(prices.length);
           int sumFloor = 0;
           int sumCeil = 0;
           
    
           for(String s:prices){
              String[] tmps = s.split("\.");
              int i = Integer.parseInt(tmps[0]);
              BigDecimal d = new BigDecimal("0."+ tmps[1]);
              sumFloor = sumFloor + i;
              if(!"000".equals(tmps[1])){
                 sumCeil = sumCeil + i + 1;
              }else{
                 sumCeil = sumCeil + i;
              }
    
              floorList.add(d);
              ceilList.add(new BigDecimal("1.000").subtract(d));
           }
    
           //判断target是否在sumFloor和sumCeil区间内
           if(target < sumFloor || target > sumCeil){
              return -1+"";
           }
    
           //确定floor和ceil的个数(直接用target-sumFloor计算得到)
           
    
           //排序舍入误差的两个数组,按照前一步计算得到的个数分别从小到大相加即可
           Collections.sort(floorList);
           Collections.sort(ceilList);
          
           BigDecimal finalResult = new BigDecimal("0.000");
    
           for(int i = 0;i < target-sumFloor;i++){
              finalResult = finalResult.add(ceilList.get(i));
           }
    
           
           for(int i=0;i<prices.length - (target-sumFloor);i++){
             finalResult = finalResult.add(floorList.get(i));
           }
    
           return finalResult.toString();
        }
    }
    
  • 相关阅读:
    poj 3280 Cheapest Palindrome(区间DP)
    POJ 2392 Space Elevator(多重背包)
    HDU 1285 定比赛名次(拓扑排序)
    HDU 2680 Choose the best route(最短路)
    hdu 2899 Strange fuction (三分)
    HDU 4540 威威猫系列故事――打地鼠(DP)
    HDU 3485 Count 101(递推)
    POJ 1315 Don't Get Rooked(dfs)
    脱离eclipse,手动写一个servlet
    解析xml,几种方式
  • 原文地址:https://www.cnblogs.com/ging/p/14252388.html
Copyright © 2011-2022 走看看