我知道这个代码/逻辑对于解决子集求和问题是错误的,但似乎无法理解为什么。
计算所有可能子集的总和,并检查是否有任何等于所需的总和。这将在O(n ^ 2)中完成,这显然是错误的,因为我可以通过DP O(n * sum)来解决这个问题。
谢谢。
int main() {
long long int t,n,i,j;
scanf("%lld",&t);
while(t--)
{
long long int p[1005][1005],s[1005][1005]={0};
long long int a[1005],sum;
long long int counter=0;
scanf("%lld %lld",&n,&sum);
for(i=0;i<n;i++)
scanf("%lld",&a[i]);
s[0][0]=a[0];
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
if(i==j)
{
s[i][j]=a[i];
}
else
{
s[i][j]=a[j]+s[i][j-1];
}
}
}
int flag=0;
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
if(s[i][j]==sum)
flag++;
}
}
if(flag)
cout<<1<<endl;
else
cout<<0<<endl;
}
return 0;
}
答案 0 :(得分:0)
您的代码的问题只是您没有计算所有子集的总和。这就是为什么你的代码看起来比实际需要的速度快得多。
答案 1 :(得分:0)
问题是s[i][j]
只记录a[i]+a[i+1]+...+a[j]
。实际上,您需要记录a[i...j]
的所有子集的总和,其应为2^(j-i)
。如果目标总和不是连续子集的总和,则代码应该很容易失败。