称砝码问题:

// 一组砝码,重量互补相等,分别为m1,m2,m3,.mn; 每种砝码的对应的数量,为x1,x2,x3,xn
    // 现在要用这些砝码去称重物体的重量(放在同一侧)。问能称出多少种不同的重量
    

解答:

分析:

设砝码分别为m1、m2……mn;他们可取的最大数量分别为x1、x2……xn 。想获取能称出多少中不同的重量,则需要把它们所有组合情况下分别相加,假设有X中组合,分别相加得到的结果分别为X1,X2...XX。X减去X1到XX中相等的个数。

思路:

//①分配一个数组temp[sum+1],初始化temp[0]和temp[sum]为true
    //②三层for循环:第一层n:表示种类,第二层:每种砝码的个数x,第三层:(int k = sum; k >= m[i]; k–)
    //③对于第三层循环需要判断temp[k - m[i]],若为true则可以将k放入数组

private static int getNums(int n, String str1, String str2) {
		String[] s1Arr = str1.split("");
		String[] s2Arr = str2.split("");
		int[] m = new int[n];
		int[] x = new int[n];
		int sum = 0;

		for (int i = 0; i < n; i++) {
			m[i] = Integer.valueOf(s1Arr[i]);
			x[i] = Integer.valueOf(s2Arr[i]);
			sum += x[i] * m[i];
		}

		boolean[] temp = new boolean[sum + 1];
		temp[0] = true;
		temp[sum] = true;

		for (int i = 0; i < n; i++) {

			for (int j = 0; j < x[i]; j++) {

				for (int k = sum;k >= m[i]; k--) {
					 if (temp[k - m[i]])//递归思想的应用
	                        temp[k] = true;//若质量相同的会被覆盖,所以不用额外处理相同的质量
					
				}
			}
		}
		int count=0;
		for (int i = 0; i <=sum; i++) {
			 if (temp[i]) {
				count++;
			}
		}
		return count;
	}
	

另一种实现方案:

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
 
public class Main {
 
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int num=scanner.nextInt();
		int []weight=new int[num];
		int []count=new int[num];
		
		for(int i=0;i<num;i++){
			weight[i]=scanner.nextInt();
		}
		for(int i=0;i<num;i++){
			count[i]=scanner.nextInt();
		}
		
		Set<Integer>set=new HashSet<Integer>();
		set.add(0);
		
		for(int i=0;i<num;i++){
			Object[]a=set.toArray();
			for(int j=1;j<=count[i];j++){
				for(int k=0;k<a.length;k++){
					Integer kk=(Integer)a[k]+weight[i]*j;
					set.add(kk);
				}
			}
			
		}
		System.out.print(set.size());
		
	}
}

代码解释:

1.当 i=0时候
    a[]={0} 数组a中只有0元素同时知道a的长度为1,j=1时候 对于第三个for循环 相当于循环一次。kk=a[0]+m1;即kk=0+m1;然后添加到集合里面,当第二个for循环进行循环      时候 j=1                  kk=0+m1;

              j=2                  kk=0+2 * m1
              j=a[1]=x1        kk=0+x1 * m1
 

j=2时候对于第三个循环  就是把a数组的每一个数分别加2*m2,然后在添加到集合中,则a为


a[]={0,           m1,                2*m1        .....         x1*m1,         m2,               m1+m2,                2*m1+m2 .....              x1*m1+m2,

        2*m2     m1+2*m2,     2*m1+2*m2   ... x1*m1+2*m2 ,   m2+2*m2,     m1+m2+2*m2,   2*m1+m2+2*m2.....   x1*m1+m2+2*m2    }

对于第二个循环 就是集合中的每一个数分别加上j*m2,然后添加到集合中

发布了668 篇原创文章 · 获赞 12 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/xiamaocheng/article/details/105344218