オンラインジャッジで古典的な部分和問題を試しています。ただし、今回の違いは、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;
}
}