蘑菇街 修理桌子

Arthur最近搬到了新的别墅,别墅特别大,原先的桌子显得比较小,所以他决定换一张新的桌子。他买了一张特别大的桌子,桌子是由很多条桌腿进行支撑的,可是回到家之后他发现桌子不稳,原来是桌子腿长度不太相同。他想要自己把桌子修理好,所以他决定移除掉一些桌腿来让桌子变得平稳。桌子腿总共有n条腿,第i条腿长度为li,Arthur移除第i桌腿要花费代价为di。假设k条腿桌子平稳的条件:超过一半桌腿能够达到桌腿长度的最大值。例如:一条腿的桌子是平稳的,两条腿的桌子腿一样长时是平稳的。请你帮Arthur计算一下是桌子变平稳的最小总代价。

输入描述:
输入:
第一行数据是一个整数:n (1≤n≤105),n表示桌腿总数。
第二行数据是n个整数:l1, l2, …, ln (1≤li≤105),表示每条桌腿的长度。
第三行数据是n个整数:d1, d2, …, dn (1≤di≤200),表示移除每条桌腿的代价。

输出描述:
输出:
输出让桌子变平稳的最小总代价

输入例子:
样例输入

6

2 2 1 1 3 3

4 3 5 5 2 1

输出例子:
8

public class Main {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
            //长度为i的桌腿的数量
            int[] arr = new int[106];
            //桌腿长度
            ArrayList<Integer> liNum = new ArrayList<>();
            //移除每条桌腿代价
            ArrayList<Integer> diNum = new ArrayList<>();
            //总代价
            int count = 0;
            int n = scan.nextInt();
            for (int i = 0; i < n; i++) {
                int li = scan.nextInt();
                liNum.add(li);
                arr[li] += 1;
            }
            for (int i = 0; i < n; i++) {
                int di = scan.nextInt();
                diNum.add(di);
                count += di;
            }
            System.out.println(sovle(liNum,diNum,arr,n,count));
        }
        scan.close();
    }

    private static int sovle(ArrayList<Integer> liNum, ArrayList<Integer> diNum,
                              int[] arr, int n, int count) {
        for (int i = 105; i > 0; i--) {
            int cost = 0;
            //长度小于i的桌腿移除代价
            ArrayList<Integer> cut = new ArrayList<>();
            if (arr[i] == 0) {
                continue;
            }
            if (arr[i] * 2 <= n) {
                //需要移除桌腿的数量
                int cutNum = n - 2 * arr[i] + 1;
                //移除比i长的桌腿
                for (int j = i + 1; j < 106; j++) {
                    cutNum -= arr[j];
                }
                for (int j = 0; j < n; j++) {
                    int li = liNum.get(j);
                    if (li < i) {
                        //长度小于i的桌腿的代价
                        cut.add(diNum.get(j));
                    }
                    if (li > i) {
                        //移除长度大于i的桌腿的代价
                        cost += diNum.get(j);
                    }
                }
                if (cut.size() > 0 && cutNum > 0) {
                    //从小到大排序
                    Collections.sort(cut);
                    //移除代价最小的桌腿cutNum
                    for (int j = 0; j < cutNum; j++) {
                        cost += cut.get(j);
                    }
                }
            }else {//长度为i的桌腿数量过半,只需把比i长的桌腿移除
                for (int j = 0; j < n; j++) {
                    if (liNum.get(j) > i) {
                        cost += diNum.get(j);
                    }
                }
            }
            if (cost < count) {
                count = cost;
            }
        }
        return count;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值