正数数组的最小不可组成和
给定一个正数数组arr,其中所有的值都为整数,以下是最小不可组成和的概念
把arr每个子集内的所有元素加起来会出现很多值,其中最小的记为min,最大的记为max
在区间[min, max]上,如果有数不可以被arr某一个子集相加得到,那么其中最小的那个数是arr的最小不可组成和
在区间[min, max]上,如果所有的数都可以被arr的某一个子集相加得到,那么max+1是arr的最小不可组成和
请写函数返回正数数组arr的最小不可组成和
import java.util.Scanner;
public class Main {
/**
* 时间复杂度O(n * sum)
* 空间复杂度O(n * sum)
*
* @param arr
* @return
*/
private static int solve1(int[] arr) {
if (arr == null || arr.length == 0) {
return 1;
}
int n = arr.length;
int min = arr[0];
int sum = 0;
for (int i = 0; i < n; ++i) {
min = Math.min(min, arr[i]);
sum += arr[i];
}
/**
* 多样本对应模型
*/
boolean[][] dp = new boolean[n][sum + 1];
/**
* base case
*/
for (int i = 0; i < n; ++i) {
dp[i][0] = true;
}
dp[0][arr[0]] = true;
/**
* dp[i][j] 前i个元素是否能组成j
* 1. 取第i个元素,dp[i - 1][j - arr[i]]
* 2. 不取第i个元素,dp[i - 1][j]
*/
for (int i = 1; i < n; ++i) {
for (int j = min; j <= sum; ++j) {
dp[i][j] = dp[i - 1][j];
if (j - arr[i] >= 0) {
dp[i][j] |= dp[i - 1][j - arr[i]];
}
}
}
int ans = sum + 1;
for (int i = min; i <= sum; ++i) {
if (!dp[n - 1][i]) {
ans = i;
break;
}
}
return ans;
}
/**
* 时间复杂度O(n * sum)
* 空间复杂度O(sum)空间压缩
*
* @param arr
* @return
*/
private static int solve2(int[] arr) {
if (arr == null || arr.length == 0) {
return 1;
}
int n = arr.length;
int min = arr[0];
int sum = 0;
for (int i = 0; i < n; ++i) {
min = Math.min(min, arr[i]);
sum += arr[i];
}
/**
* 多样本对应模型
*/
boolean[] dp = new boolean[sum + 1];
/**
* base case
*/
dp[0] = true;
dp[arr[0]] = true;
/**
* dp[i][j] 前i个元素是否能组成j
* 1. 取第i个元素,dp[i - 1][j - arr[i]]
* 2. 不取第i个元素,dp[i - 1][j]
*/
for (int i = 1; i < n; ++i) {
/**
* 反向遍历,防止覆盖
*/
for (int j = sum; j >= min; --j) {
if (j - arr[i] >= 0) {
dp[j] |= dp[j - arr[i]];
}
}
}
int ans = sum + 1;
for (int i = min; i <= sum; ++i) {
if (!dp[i]) {
ans = i;
break;
}
}
return ans;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; ++i) {
arr[i] = in.nextInt();
}
System.out.println(solve1(arr));
}
}
}
心之所向,素履以往 生如逆旅,一苇以航

浙公网安备 33010602011771号