砝码称重问题的三个解法

问题描述

在这里插入图片描述

一、

这种方法太麻烦了,不建议,总体思路是把所有可能组合的情况找到,然后去除重复的,拿到结果

package Weight;

import java.util.Scanner;

public class Weight {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int arr[]=new int[6];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = scanner.nextInt();
        }
        Weight weight = new Weight(arr);
        //ArrayList result = new ArrayList();
        int result[];
        //计算
        result = concole(0,weight);
        result = flush(result);
        int x = 0;
        for (int i = 0; i < result.length; i++) {
            if (result[i] != 0) x++;
        }
        System.out.println("Total="+x);
        
    }
    int weight_arr[] = new int[6];
    int num_arr[] ;
    int con_arr[][];
    Weight(int arr[]){
        weight_arr[0] = 1;
        weight_arr[1] = 2;
        weight_arr[2] = 3;
        weight_arr[3] = 5;
        weight_arr[4] = 10;
        weight_arr[5] = 20;
        num_arr = arr;
        int con_len = 0;
        for (int i = 0,j=0; i < 6; i++) {
            if(num_arr[i]>0){
                con_len++;
            }
        }
        con_arr = new int[con_len][];
        for (int i = 0,j = 0; i < num_arr.length; i++) {
            if(num_arr[i]>0){
                con_arr[j++] = new int[num_arr[i]+1];
            }
        }
        int tmp_index = 0;
        for (int i = 0; i < con_arr.length; i++) {
            if (num_arr[tmp_index]>0){
                for (int j = 0; j < con_arr[i].length; j++) {
                        con_arr[i][j] = j*weight_arr[tmp_index];
                }
            }else {
                i--;
            }
            tmp_index++;

        }
    }
    public static int[] concole(int index,Weight weight){
        if(index == weight.con_arr.length-1){
            int arr[]=new int[weight.con_arr[index].length];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = weight.con_arr[index][i];
            }
            return arr;
        }
        //把当前行拿出来
        int arr[]=new int[weight.con_arr[index].length];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = weight.con_arr[index][i];
        }
        //剩下的行递归,拿到结果数组
        int result[] = concole(index+1,weight);
        //把结果数组加到返回的数组中
        int return_arr[] = new int[result.length*arr.length];
        for (int i = 0; i < arr.length; i++) {
            int tmp = arr[i];
            int tmp_arr[] = new int[result.length];
            for (int j = 0; j < tmp_arr.length; j++) {
                tmp_arr[j] = result[j]+tmp;
            }
            System.arraycopy(tmp_arr, 0, return_arr, i*result.length, tmp_arr.length);
        }
        return return_arr;
    }
    public static int[] flush(int arr[]){
        int return_arr[] = new int[arr.length];
        int index = 0 ;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] != 0 && arr[i] != -1){
                int x = arr[i];
                for (int j = i+1; j < arr.length; j++) {
                    if (arr[j] == x){
                        arr[j] = -1;
                    }
                }
                return_arr[index++] = x;
            }
        }
        return  return_arr;
    }
}

二、回溯法

package Weight;

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
/*
*功能描述:砝码称重问题
*return:
* 思路分析:先输入各个砝码的个数组成一个数组,
 * weights表示每一种砝码的重量
 * weightsTotal把能表示的重量放入该容器中
 * total表示能表示的重量的个数
 * curweight表示当前的重量
*/
public class Weight3 {
    static int[] weights= {1,2,3,5,10,20};
    static Set<Integer> weightsTotal = new HashSet<>();
    static int total=0;
    static int curweight=0;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scanner =new Scanner(System.in);
        int[] n=new int[6];
        for(int i=0;i<6;i++) {
            n[i]=scanner.nextInt();
        }
        totalWeight(n,0);
        System.out.print("Total="+(total-1));
    }
    static void totalWeight(int[] n,int cycleIndex) {
        /*
        *cycleIndex表示计算哪一种砝码,如果=6表示到头了,直接返回
        * weightNum是这一种砝码的数量,如果数量为0,执行下一种
        * 如果数量不为0,weight为这一种砝码的重量,
        * 循环这种砝码的数量,从0-weightNum,curweight+=当前砝码的重量*当前数量,
        * 如果当前重量在容器中没有,那就把当前重量加进去,total++,然后递归调用cycleIndex+1,
        * 然后curweight-=当前砝码的重量*当前数量,循环下一次
        */
        if(cycleIndex==6) {
            return;
        }
        int weightNum=n[cycleIndex];
        if(weightNum==0) {
            totalWeight(n,cycleIndex+1);
        }else {
            int weight=weights[cycleIndex];
            for(int i=0;i<=weightNum;i++) {
                curweight+=weight*i;
                if(!weightsTotal.contains(curweight)) {
                    total++;
                    weightsTotal.add(curweight);
                }
                totalWeight(n,cycleIndex+1);
                curweight-=weight*i;
            }
        }

    }
}

三、暴力循环

package Weight;
import java.util.Scanner;
/*
*功能描述:砝码称重问题
*return:
* 思路解析:先输入各个砝码的个数,然后求出这些砝码的最大的重量
 * 然后建立一个数组,长度就是砝码最大重量加一
 * 开始一个六层的循环,重量从0开始递增,如果可以得到该重量,数组的该位置就设为1,以此类推
 * 最后计算数组的1的个数为result
 * result减去一个0的位置就是结果
*
*/
public class Weight2 {
    public static void main(String[] args) {
        int list[] = new int[6];
        int sum = 0;
        Scanner scanner = new Scanner(System.in);
        for (int i = 0; i < 6; i++) {
            list[i] = scanner.nextInt();
        }
        sum = list[0] * 1 + list[1] * 2 + list[2] * 3 + list[3] * 5 + list[4] * 10 + list[5] * 20;
        int[] temp = new int[sum + 1];
        for (int i = 0; i <= list[0]; i++) {
            for (int j = 0; j <= list[1]; j++) {
                for (int k = 0; k <= list[2]; k++) {
                    for (int l = 0; l <= list[3] ;l++) {
                        for (int m = 0; m <= list[4]; m++) {
                            for (int n = 0; n <= list[5]; n++) {
                                temp[i*1 + j*2 + k*3 + l*5 + m*10 + n*20] = 1;
                            }
                        }
                    }
                }
            }
        }
        int result = 0;
        for (int i = 0; i <= sum ; i++) {
            if (temp[i] == 1) result++;
        }
        System.out.println("Total="+(result-1));

    }
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值