首页 > 试题广场 >

正数数组的最小不可组成和

[编程题]正数数组的最小不可组成和
  • 热度指数:1028 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个正数数组arr,其中所有的值都为整数,以下是最小不可组成和的概念
  • 把arr每个子集内的所有元素加起来会出现很多值,其中最小的记为min,最大的记为max
  • 在区间[min, max]上,如果有数不可以被arr某一个子集相加得到,那么其中最小的那个数是arr的最小不可组成和
  • 在区间[min, max]上,如果所有的数都可以被arr的某一个子集相加得到,那么max+1是arr的最小不可组成和
请写函数返回正数数组arr的最小不可组成和
时间复杂度为,额外空间复杂度为

输入描述:
第一行一个整数N,表示数组长度。
接下来一行N个整数表示数组内的元素。


输出描述:
输出一个整数表示数组的最小不可组成和
示例1

输入

3
2 3 9

输出

4
示例2

输入

3
1 2 4

输出

8

说明

3 = 1 + 2
5 = 1 + 4
6 = 2 + 4
7 = 1 + 2 + 4

备注:


#include <bits/stdc++.h>
using namespace std;
int main(){
    int n, r, s=0, Min=INT_MAX;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
        s += a[i];
        Min = min(Min, a[i]);
    }
    bool dp[s+1];
    memset(dp, false, sizeof(dp));
    dp[0] = true;
    for(int i=0;i<n;i++)
        for(int j=s;j>=a[i];j--)
            dp[j] = dp[j] || dp[j-a[i]];
    r = s+1;
    for(int i=Min;i<=s;i++)
        if(!dp[i]){
            r = i;
            break;
        }
    cout<<r<<endl;
    return 0;
}

编辑于 2020-03-26 00:52:45 回复(0)
lens = int(input())
arr = [int(i.strip()) for i in input().split() if i.strip()]

res = {}
mins = min(arr)
maxs = sum(arr)

dp = [[False for _ in range(maxs + 1)] for _ in range(lens)]
dp[0][arr[0]] = True

for ind in range(1, lens):
    for sums in range(maxs + 1):
        dp[ind][sums] = True if arr[ind] == sums&nbs***bsp;dp[ind - 1][sums - arr[ind]]&nbs***bsp;dp[ind - 1][sums] else False

r = maxs + 1
for i in range(mins, maxs + 1):
    if not dp[-1][i]:
        r = i
        break
print(r)

发表于 2022-10-23 08:46:02 回复(0)