题目描述:
给你一个整数M和数组N,N中的元素为连续整数,要求根据N中的元素组装成新的数组R,组装规则:
1.R中元素总和加起来等于M
1.R中的元素可以从N中重复选取
2.R中的元素最多只能有1个不在N中,且比N中的数字都要小(不能为负数)
请输出:数组R一共有多少组装办法
输入描述:
第一行输入是连续数组N,采用空格分隔
第二行输入数字M
输出描述:
输出的是组装办法数量,int类型
补充说明:
1 <= N.length <= 30
1 <= N.length <= 1000
收起
示例1
输入:
2
5
输出:
1
说明:
只有1种组装办法,就是[2,2,1]
示例2
输入:
2 3
5
输出:
2
说明:
一共2种组装办法,分别是[2,2,1],[2,3]
import java.util.Scanner;
public class Main {
static int ans = 0;
static int min = Integer.MAX_VALUE;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String [] s = in.nextLine().split(" ");
int M = in.nextInt();
int [] n = new int[s.length];
for (int i = 0; i < s.length; i++) {
n[i] = Integer.parseInt(s[i]);
min = Math.min(min,n[i]);
}
dfs(0,n,M,0);
System.out.println(ans);
}
public static void dfs(int idx,int [] n, int value, int currV){
if(currV==value){
ans++;
return;
}
if(currV>value){
return;
}
if(value-currV<=min-1){
ans++;
return;
}
for (int i = idx; i < n.length; i++) {
//选这个数字
dfs(i, n,value,currV+n[i]);
}
}
}
N = list(map(int, input().split()))
M = int(input())
N.sort()
length = len(N)
count = 0
# lis = [0] * length
# reach_max = []
# for i in range(length):
# reach_max.append(M // N[i])
# pos = len(lis) - 1
# while True:
# if pos == -1:
# break
# while pos < length-1 and lis[pos] <= reach_max[pos]:
# sum_res = 0
# for i in range(length):
# sum_res += N[i] * lis[i]
# delta = M - sum_res
# if 0 <= delta < N[0]:
# count += 1
# pos -= 1
if length == 1:
count = 1
elif length == 2:
count = 2
elif length == 3:
for i in range(0, M // N[0] + 1):
for j in range(0, M // N[1] + 1):
for k in range(0, M // N[2] + 1):
sum_res = N[0] * i + N[1] * j + N[2] * k
delta = M - sum_res
if delta < 0:
break
if 0 <= delta < N[0]:
count += 1
elif length == 4:
for i in range(0, M // N[0] + 1):
for j in range(0, M // N[1] + 1):
for k in range(0, M // N[2] + 1):
for a in range(0, M // N[3] + 1):
sum_res = N[0] * i + N[1] * j + N[2] * k + N[3] * a
delta = M - sum_res
if delta < 0:
break
if 0 <= delta < N[0]:
count += 1
elif length == 5:
for i in range(0, M // N[0] + 1):
for j in range(0, M // N[1] + 1):
for k in range(0, M // N[2] + 1):
for a in range(0, M // N[3] + 1):
for b in range(0, M // N[4] + 1):
sum_res = N[0] * i + N[1] * j + N[2] * k + N[3] * a + N[4] * b
delta = M - sum_res
if delta < 0:
break
if 0 <= delta < N[0]:
count += 1
elif length == 6:
for i in range(0, M // N[0] + 1):
for j in range(0, M // N[1] + 1):
for k in range(0, M // N[2] + 1):
for a in range(0, M // N[3] + 1):
for b in range(0, M // N[4] + 1):
for c in range(0, M // N[5] + 1):
sum_res = N[0] * i + N[1] * j + N[2] * k + N[3] * a + N[4] * b + N[5] * c
delta = M - sum_res
if delta < 0:
break
if 0 <= delta < N[0]:
count += 1
print(count)
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
set<vector<int>> res;
void dfs(vector<int>const& nums, int start_index, int target, int max_ext_val, vector<int> path) {
if (target < 0)
return ;
if (target == 0 || target < max_ext_val) {
res.insert(path);
return ;
}
for (int i = start_index; i < nums.size(); ++i) {
path.push_back(nums[i]);
dfs(nums, i, target - nums[i], max_ext_val, path);
path.pop_back();
}
}
int main() {
int value;
vector<int> N;
while (cin >> value) {
N.push_back(value);
}
int M = N.back();
N.pop_back();
int min_value = *min_element(N.begin(), N.end());
dfs(N, 0, M, min_value, {});
cout << res.size();
return 0;
}