Zoj 2868 Incredible Cows (分半dfs暴搜)

来源:互联网 发布:java设置全局编码格式 编辑:程序博客网 时间:2024/06/16 19:21

对于一个超出范围暴搜问题,尝试分一半暴搜求解

/*Zoj 2868 Incredible Cows时间: 2017/02/18题意:将一堆数分成两堆,使两堆和差最小题解:直接暴力2^34,分成两堆优化,将一堆暴力预处理所有可能的和,将和排序后,在另一堆暴力出和后,寻找于第一堆相加最接近sum/2的值,枚举找出最小答案。*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <map>using namespace std;#define LL long long#define INF 0x3f3f3f3f#define PI acos(-1.0)#define E 2.71828#define MOD 1000000007#define N 110#define M 5010int a[N],vis[1<<18];int n,m,ans,half,sum;int k;void dfs1(int depth,int val){    if(depth == m)    {        vis[k++] = val;        return ;    }    dfs1(depth+1,val);    dfs1(depth+1,val+a[depth]);}void dfs2(int depth,int val){    if(depth == n)    {        int id = lower_bound(vis,vis+k,half-val)-vis;        if(id < k)            ans = min(ans,abs(sum-2*(vis[id]+val)));        return ;    }    dfs2(depth+1,val);    dfs2(depth+1,val+a[depth]);}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        sum = 0;        for(int i = 0; i < n; i++)        {            scanf("%d",&a[i]);            sum += a[i];        }        half = sum/2;        m = n/2;        k = 0;        ans = sum;        dfs1(0,0);        sort(vis,vis+k);        dfs2(m,0);        printf("%d\n",ans);    }    return 0;}




0 0
原创粉丝点击