如何查找子序列中等于总和的最大子集的大小
How to find size of largest subset of a sub-sequence equal to a sum
我有这个问题来自黑客地球
给定一个由 N 个整数、C 卡和 S 和 S 和组成的数组。每张卡都可以使用 将给定数组中的整数递增或递减 1。 查找是否有任何子集(在使用任何编号的卡之后/之前)与 给定数组中的 S 总和。
输入格式
输入的第一行包含一个整数 T,表示编号。 测试用例。每个测试用例有 2 行输入。每个的第一行 测试用例有三个整数N(数组的大小),S(子集和)和 C(卡的编号)。每个测试用例的第二行有 N 个整数 数组(a1 到 aN)由空格分隔。
约束
1<=T<=100
1<=N<=100
1<=S<=10000
0<=C<=100
1<=ai<=100输出格式
如果存在具有给定总和的子集,则打印 TRUE,否则打印 FALSE。
所以这基本上是子集和问题的变体,但不是找出具有总和S
的给定子集是否存在,我们需要找到从序列index
到N-1
的最大子集,其值为s
,并将其长度与我们的C
值进行比较,看看它是否更大。如果是,那么我们有足够的元素来使用我们的C
卡修改总和,然后我们打印出我们的答案。这是我的代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int N, S, C;
int checkSum(int index, int s, vector<int>& a, vector< vector<int> >& dP) {
if (dP[index][s] != -1)
return dP[index][s];
int maxNums = 0; // size of maximum subset array
for (int i = index; i < N; i++) {
int newSum = s - a[i];
int l = 0;
if (newSum == 0) {
l = 1;
} if (newSum > 0) {
if (i < (N-1)) { // only if we can still fill up sum
l = checkSum(i + 1, newSum, a, dP);
if (l > 0) // if it is possible to create this sum
l++; // include l in it
} else {
// l stays at 0 for there is no subset that can create this sum
}
} else {
// there is no way to create this sum, including this number, so skip it;
if (i == (N-1))
break; // don't go to the next level
// and l stays at 0
}
if (l > maxNums) {
maxNums = l;
}
}
dP[index][s] = maxNums;
return maxNums;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> N >> S >> C;
vector<int> a(N);
for (int i = 0; i < N; i++)
cin >> a[i];
vector< vector<int> > dP(N, vector<int>(S + C + 2, -1));
bool possible = false;
for (int i = 0; i <= C; i++) {
int l = checkSum(0, S-i, a, dP);
int m = checkSum(0, S+i, a, dP);
if ( (l > 0 && l >= i) || (m > 0 && m >= i) ) {
cout << "TRUE" << endl;
possible = true;
break;
}
}
if (!possible)
cout << "FALSE" << endl;
}
return 0;
}
所以基本上,0 表示不可能从元素索引到 N-1 创建一个等于 s 的子集,而 -1 表示我们还没有计算它。任何其他值表示总和为 s 的最大子集的大小。此代码未通过所有测试用例。怎么了?
您错过了以下行中的else
} if (newSum > 0) {
在某些情况下,这会使您的程序在按l
更新maxNums
之前有一个意外的提前休息。
例如,N=1、S=5、C=0、a={5}
潜在的逻辑问题
您已将要使用的卡号限制为不超过子集大小,而问题从未说明您不能将多张卡应用于相同的整数。
我的意思是l >= i
和m >= i
if ( (l > 0 && l >= i) || (m > 0 && m >= i) ) {
看来你有逻辑缺陷。
您需要找到最短的子集(总和在范围S-C..S+C
)并将其大小与C
进行比较。如果子集较短,则可以进行所需的总和。
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 这种用于查找连续子数组中最大和的递归算法有什么优势吗?
- 斐波那契数列部分和的最后一位数字
- 为什么同时覆盖全局新运算符和特定于类的运算符不是模棱两可的行为?
- 如何有效地找到数组中三元组和的最小差异?
- 计算校验和的逐位运算符
- 找到 2 个相等和的子序列,最大总和?
- 返回混合 \ 和 / 的文件系统路径字符串方法
- *、/ 和 % 的定义如何保证 a/b * b + a%b == a
- 带有空格和","的Cin
- 在这里,我编写了一个使用 2 维数组并打算执行行和的 C++ 代码,但它没有给出正确的输出
- 在二叉搜索树中查找最小和的算法改进
- (void*)和的含义是什么
- 为什么"---"和"+ ++"和"+++"的操作方式不同?
- 提升精神中>和>>的区别
- C++:用于查找最小周期边和的快速算法
- 找出最大连续子序列和的开始和结束
- .cpp 和 的常量.R 文件
- 这C++代码的安全性和独立于编译器的程度
- 计算类似于二项和的条件概率