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

链接:https://www.nowcoder.com/questionTerminal/f5368cd8008d41f58b2da7ced2f4d809
来源:牛客网

给定一个正数数组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

思路:这个题和【数字和为sum的方法数】这个题很像,都是背包问题的变形,用动态规划做。
在这里插入图片描述
在这里插入图片描述
代码:

#include<iostream>
#include<vector>
using namespace std;
int Min_No_Sum(vector<int> v, int n)
{
	int max = v[0];
	int min = v[0];
	for (int i = 1; i < n; i++)
	{
		if (v[i] < min)
			min = v[i];
		max += v[i];
	}
	vector<vector<int>> buf(n + 1, vector<int>(max + 1, 0));
	for (int i = 0; i < n + 1; i++)
		buf[i][0] = 1;
	for (int i = 1; i < n + 1; i++)
	{
		for (int j = 1; j < max + 1; j++)
		{
			if (v[i - 1] > j || buf[i - 1][j] != 0)
				buf[i][j] = buf[i - 1][j];
			else
				buf[i][j] = buf[i - 1][j - v[i - 1]];

		}
	}
	for (int i = min; i < max + 1; i++)
	{
		if (buf[n][i] == 0)
			return i;
	}
	return max + 1;
}
int main()
{
	int n;
	while (cin >> n)
	{
		vector<int> v(n);
		for (int i = 0; i < n; i++)
			cin >> v[i];
		cout << Min_No_Sum(v, n) << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值