选数 中途相遇搜索

Posted EZ_WYC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了选数 中途相遇搜索相关的知识,希望对你有一定的参考价值。

题目

题目在这里

思路

就是个搜索啊

代码

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <set>
#include <algorithm>
#include <cstdio>

using namespace std;

const int N = 25;

int a[N];

int n;

struct Data
{   int val, status;
    bool operator < (const Data & rhs) const { return val < rhs.val; }
} num[1000010];
int tot;

void dfs_1(int x, int sum, int S)
{   if(x == n/2+1)
        num[++tot] = (Data){sum, S};
    else
    {   dfs_1(x+1, sum, S);
        dfs_1(x+1, sum-a[x], S|(1<<x));
        dfs_1(x+1, sum+a[x], S|(1<<x));
    }
}

bool vis[2097153];

void dfs_2(int x, int sum, int S)
{   if(x == n+1)
    {   int l = lower_bound(num+1, num+1+tot, (Data){-sum, 0}) - num;
        int r = upper_bound(num+1, num+1+tot, (Data){-sum, 0}) - num;
        for(int i=l; i<r; i++)
            vis[S|num[i].status] = 1; //大神犇tzw说这样可能会T
    }
    else
    {   dfs_2(x+1, sum, S);
        dfs_2(x+1, sum-a[x], S|(1<<x));
        dfs_2(x+1, sum+a[x], S|(1<<x));
    }
}

int main()
{   scanf("%d", &n);
    for(int i=1; i<=n; i++)
        scanf("%d", &a[i]);
    dfs_1(1, 0, 0);
    sort(num+1, num+1+tot);
    dfs_2(n/2+1, 0, 0);
    int ans = 0;
    for(int i=0; i<=2097152; i++) if(vis[i]) ans++; //千万不要用set去重, 特别慢
    printf("%d\n", ans-1);
    return 0;
}

配注

其实这是我第一次写中途相遇搜索

写了一坨bug

以上是关于选数 中途相遇搜索的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 4431 Mahjong (模拟+搜索+哈希+中途相遇)

算法优化策略之“中途相遇”算法思想

HDU - 5936: Difference(中途相遇法)

Codeforces 525E Anya and Cubes 中途相遇法

Prime Gift CodeForces - 912E (中途相遇)

HDU 5936 Difference 中途相遇法(中国大学生程序设计竞赛(杭州))