砝码称重问题的三个解法

问题描述

在这里插入图片描述

一、

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

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));

    }
}

猜你喜欢

转载自blog.csdn.net/Walker7143/article/details/106133148