题目描述

给你一个整数 组装新的数组_java和数组组装新的数组_java_02组装新的数组_java_02中的元素为连续整数,要求根据组装新的数组_java_02中的元素组装成新的数组组装新的数组_数组_05 组装规则:

  1. 组装新的数组_数组_05中元素总和加起来等于组装新的数组_java
  2. 组装新的数组_数组_05中的元素可以从组装新的数组_java_02中重复选取
  3. 组装新的数组_数组_05中的元素最多只能有 1 个不在组装新的数组_java_02中,且比组装新的数组_java_02中的数字都要小(不能为负数)

输入描述

第一行输入是连续数组组装新的数组_java_02,采用空格分隔 第二行输入数字组装新的数组_java

输出描述

输出的是组装办法数量,int 类型

备注

组装新的数组_用例_15组装新的数组_用例_16

用例

用例1

输入

2
5

输出

1
说明:只有一种组装方法,就是 [2,2,1]

用例2

输入

2 3
5

输出

2
说明:一共有两种组装方法,分别是 [2,2,1] [2,3]

题目解析

直接上代码

package com.hw;



import java.util.Arrays;
import java.util.Scanner;

public class ArrayComposer {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String line = in.nextLine();
        int M = Integer.parseInt(in.nextLine());
        String[] split = line.split(" ");
        int[] N = new int[split.length];
        for (int i = 0; i < split.length; i++) {
            N[i] = Integer.parseInt(split[i]);
        }
        arrayComposer(M, N);
    }

    /*
     *   这里通过示例可以知道,很显然 0 不被考虑在内。那么如果数组 N 中最小的数字是 1 ,那么就没有办法使用额外的元素来组装数组 R 了。
     *   那么 如果数组 N 中最小的元素都比 M 大呢?很显然,可以选择 数字 M ,这个时候仅有一种 组装方法了
     *
     *   --那么好,首先需要对数组 N 进行排序,然后记录一下 数组 N 中的最小元素 为 min
     *   --这个时候,需要考虑 什么样的组合可以添加一个 比 min 小的元素,来完成一种组装方法 (这里根据示例,需要注意的是,[2, 2, 1] 是一种组合方法 和 [1, 2, 2] 是相同的)
     *   --那么好,需要考虑如何去重
     *   --1. 记当前组合的和为 local 如果  M - local < min 的话,那么证明可以选择一个比 min 小的数字,视为一种组装方法。
     *   --2. 如何去重,那么就是每一个元素仅选取比自己大的元素
     *
     * 那么递归的签名函数就比较好想了
     * 1.当前路线所有数字的总和
     * 2.当前的数组索引下标,然后去选择大于等于当前索引下标的元素
     *
     */
    private static int[] N;
    private static int min;
    private static int M;

    private static int ans;

    private static void arrayComposer(int m, int[] n) {
        Arrays.sort(n);
        min = n[0];
        N = n;
        M = m;

        dfs(0, 0);

        System.out.println(ans);
    }

    private static void dfs(int idx, int local) {
        // 终止条件
        if(local == M) {
            ans += 1;
            return;
        }
        if(M > local && M - local < min) {
            ans += 1;
            return;
        }
        if(local > M) {
            return;
        }

        for(int i = 0;i < N.length;i++) {
            if(idx <= i) {
                dfs(i, local += N[i]);
            }
        }
    }

}