-4

这个问题快把我逼疯了。顶部的代码在我的计算机上执行大约 0.3 秒,而底部的代码执行大约 2.7 秒。但是,我尝试将第二个代码调整为尽可能与第一个代码相似,但它似乎总是更慢。谁能告诉我为什么第一个代码的执行速度比第二个快得多?

更快的代码

#include <cstdio>
#include <set>
#define ls(x) (x & (-x))
using namespace std;
int tc, n;
set<long long> s;
long long p, a[35];
int main () {
    freopen("mini3b.in","r",stdin);
    scanf("%d", &tc);
    while (tc--) {
        s.clear();
        scanf("%lld%d", &p, &n);
        for (int i = 0; i < n; ++i) scanf("%lld", &a[i]);
        int h = n/2;
        for (int i = 0; i < (1<<h); ++i) {
            long long sum = 0;
            for (int j = 0; j < h; ++j) if (i&(1<<j)) sum += a[j];
            s.insert(sum);
        }
        bool found = false;
        for (int i = 0; (i < (1<<(n-h))) && !found; ++i) {
            long long sum = 0;
            for (int j = 0; j < n-h; ++j) if (i&(1<<j)) sum += a[h+j];
            if (s.find(p-sum) != s.end()) found = true;
        }
        printf(found? "YES\n":"NO\n");
    }
}

较慢的代码

#include <cstdio>
#include <set>
using namespace std;
long long n, bars[35];
int t, p;
set<long long> s;
int main(){
    freopen("mini3b.in","r", stdin);
    scanf("%d", &t);
    while (t--){
        s.clear();
        scanf("%lld%d", &n, &p);
        for (int i=0;i<p;++i) scanf("%lld", &bars[i]);
        int limit=p/2;
        for (int i=0;i<(1<<limit);++i){
            long long sum=0;
            for (int j=0;j<limit;++j) if (i&(1<<j)) sum+=bars[j];
            s.insert(sum);
        }
        bool found=false;
        for (int i=0;i<(1<<(n-limit))&&!found;++i){
            long long sum=0;
            for (int j=0;j<p-limit;++j) if (i&(1<<j)) sum+=bars[limit+j];
            if (s.find(n-sum) != s.end()) 
                found=true;
        }
        printf(found?"YES\n":"NO\n");
    }
}
4

1 回答 1

3

在第 4 个 for 循环中,您有

for (int i = 0; (i < (1<<(n-h))) && !found; ++i) { // fast one
                          ^

反对

for (int i=0;i<(1<<(n-limit))&&!found;++i){ // slow one
                    ^

请注意,快速代码中的“n”是慢代码中的“p”。所以你应该有

for (int i=0;i<(1<<(p-limit))&&!found;++i){ // slow one
                    ^
于 2013-03-05T12:04:59.000 回答