给出一组数字,检查是否可以将其划分为两个子集,以使两个子集中的元素之和相同或不同 我在C ++(g ++ 5.4)中遇到了此问题的分段错误。 这是我用C ++提交解决方案的地方
https://practice.geeksforgeeks.org/problems/subset-sum-problem/0
我正在检查数组是否可以分为两个相等的部分。所以我只是在检查是否存在一个总和等于数组总和一半的子集
我已经通过动态编程实现了以下逻辑
让dp [i] [j]表示是或否,是否可以使用范围为[0,i](均包括在内)的元素构成总和为j的子集,其中i是基于0的索引。对于这个传统问题,我没有做任何新的事情。但是我遇到了细分错误。该程序为小型测试用例提供正确的输出。我犯了什么错误
我没有使用任何评论,因为我没有做任何新的事情。希望这是可以理解的。
#include <iostream>
#include <bits/stdc++.h>
#include<cstdio>
#define ll long long int
using namespace std;
bool isVowel(char c){
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
bool isLower(char c){
return 97 <= c && c <= 122;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cout << setprecision(10);
ll t, n;
cin >> t;
while (t--) {
cin >> n;
ll a[n];
ll sum = 0;
for (ll i = 0; i < n; i++) {
cin >> a[i];
sum += a[i];
}
if (sum % 2) {
cout << "NO" << '\n';
continue;
}
sum /= 2;
ll dp[n][sum + 1];
for (ll i = 0; i < n; i++) {
for(ll j = 0; j < sum + 1; j++) {
dp[i][j] = 0;
}
}
for (ll i = 0; i < n; i++) {
dp[i][a[i]] = 1;
dp[i][0] = 1;
}
for (ll i = 1; i < n; i++) {
for (ll j = 1; j < sum + 1; j++){
if (j - a[i] > 0) {
dp[i][j] = dp[i - 1][j - a[i]];
}
dp[i][j] |= dp[i - 1][j];
}
}
cout << (dp[n - 1][sum] ? "YES" : "NO") << '\n';
}
}
答案 0 :(得分:1)
细分错误是由于
ll dp[n][sum + 1];
尽管约束条件说 1 <= N <= 100,0 <= arr [i] <= 1000 ,但使用的测试用例可能要大得多,因此 ll dp [ n] [sum + 1] 会占用大量的堆栈内存,请使用
bool dp[n][sum + 1];
应该工作正常。
另一方面,请避免随机使用ll,请根据约束条件使用它们。