木板切割(Java)

题目

在这里插入图片描述

  • 思路如下
    • 将n根木板合并成一根木板,只需要合并n-1次. 所L以循环的条件n>1
    • 找出n根木板里的最小和次小的木板,对其进行合并,合并长度记为t
    • 删除L里面的最小和次小的木板,并将t添加到L里面去(这里可用一个数组来删除)
    • 依次类推,直到L里面只剩下一根木板.,不能合并为止.

方法一 有的情况不能考虑到,如果数组为[8,5,3] 那么经过找最小和次小的数的时候,都会为3,那么程序会报错.
自己可以去验证下

package day03;

import java.util.*;

public class 板子切割问题 {
    public static void main(String[] args) {
        int n = 3;
        int[] l = {8,5,8};
        int minMoney = getMinMoney(n, l);
        System.out.println(minMoney);
    }

    //参数说明 n代表有多少块板子
    //l 代表板子切割的长度
    //返回 最小的金额
    public  static  int getMinMoney(int n,int[] l){

        int temp = 0;
        int ans = 0;
        //当板子的数量小于或等于1的时候就退出循环
        while (n>1){
            //代表最小长度板子的索引
            int min1 = 0;
            //代表次小板子长度的索引
            int min2 = 1;
            if(l[min1]>l[min2]){
                //如果min1大于min2所指向的长度就需要交换位置
                temp  = min1;
                min1 = min2;
                min2 = temp;
            }

            //从索引2开始比较 寻找最小的板子.
            //因为0和1已经代表了最小和次小板子的长度
            for (int i = 2; i <n ; i++) {
                if(l[i]<l[min1]){
                    //如果l[i]小于 min1所指向板子的长度,
                    //就将min1指向i  min2指向min1
                    min1 = i;
                    min2 = min1;
                }else if(l[i]<l[min2]){
                    //这说明 l[i]大于l[min1]板子的长度,但小于l[min2]板子的长度
                    //就将min2指向i
                    min2 = i;
                }
            }
            //循环结束 min1和min2就指向了最小和次小板子的长度
            //计算l[min1]+l[min2] 为上一块板子的长度 因为l[min1]+l[min2]是由一块板子切割下来的
            int t = l[min1]+l[min2];
            ans+=t;
            //更新数组
            //使用一共新的数组来存储
            //比如 原数组为[8,5,8] min1指向5 min2指向8 和为13,那么这个新数组为[8,13]
            int[] arr  = new int[n-1];
            int count= 0;
            //这个循环的作用是删除min1和min2指向的数据
            for (int i = 0; i < l.length; i++) {
                if(i!=min1  && i!=min2){
                    arr[count] = l[i];
                    count++;
                }
            }
            //将t添加到arr数组
            arr[count] = t;
            //将arr数组赋值给l 重新去计算
            l = arr;
            n--;
        }
        //循环结束 arr里面只剩下一共值,这个值就是所需要的最小费用
        return  ans;
    }

}

方法二: 用list集合来代替
思路如下:

  1. 定义一个变量ans,记录所需要的最少的费用
  2. 先去list集合找到最小的数,记录下来,并且删除最小的数(Cur1)
  3. 再去list集合找最小的数,记录下来,这个数相对于上面最小的数的次小的数,并且删除掉(Cur2)
  4. 合并两个最小的木板,t = (Cur1+Cur2), 并ans+=t
  5. 将t添加到list集合,继续进行合并.

代码如下

 public  static  int getMinMoney1(int n,List<Integer> list){
        int ans = 0;
        while (n>1){
            //记录第一小的木板
            int min1 = 0;

            //记录第二小的木板
            int min2 = 0;

            //找出第一小的木板
            for (int i = 0; i < list.size(); i++) {
                if(list.get(i)<list.get(min1)){
                    min1 = i;
                }
            }
            //删除第一小的木板
            int min1C = list.remove(min1);

            for (int i = 0; i < list.size(); i++) {
                if(list.get(i)<list.get(min2)){
                    min2 = i;
                }
            }

            //找出第二小的木板
            int min2C = list.remove(min2);

            //合并木板
            int t = min1C+min2C;
            list.add(t);
            ans+=t;
            n--;
        }
        return  ans;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值