我正在在线法官上尝试经典的子集和问题。但是,这次的不同之处在于 n<=30,因此最大操作数可以达到 30*2^30。我已经在下面有一些工作代码。但是,程序的时间限制是 1 秒,我的程序在 0.5 到 1.1 秒之间徘徊。尽管我已尽我所能加快我的代码速度,但这会导致 TLE。你们对我如何能够进一步加快和优化我的代码有什么建议吗?提前致谢。
#include <iostream>
#include <cstdio>
using namespace std;
unsigned power(unsigned x, unsigned y){ //pow function
unsigned sum=x;
for (int i=1;i<=y-1;i++)
sum*=x;
return sum;
}
int main(){
unsigned t, n, p, sum, sum2, tmpsum=0;
unsigned bars[32];
bool found;
scanf("%u", &t);
while (t--){
tmpsum=0;
found=false;
scanf("%u %u", &n, &p);
for (int i=0;i<p;i++){
scanf("%u",&bars[i]);
tmpsum+=bars[i];
}
if (tmpsum<n)found=false;
unsigned end=power(2,p)-1; //counting from the end and from the start
for (unsigned i=0;i<power(2,p)&&tmpsum>=n;i++){ //counting from 1 to 2^n in binary
sum=0;
sum2=0;
for (unsigned j=0;j<p;j++){
if (i&(1<<j))
sum+=bars[j];
if (end&(1<<j)) //counting from the end and start at the same time
{sum2+=bars[j];end--;}
}
if (sum==n||sum2==n)
{found=true;break;}
}
cout<<(found==true?"YES":"NO")<<endl;
}
}