北大OJ3977

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
const int maxint = -1u>>1;
template <class T> bool get_max(T& a, const T &b) {return b > a? a = b, 1: 0;}
template <class T> bool get_min(T& a, const T &b) {return b < a? a = b, 1: 0;}
int l1, l2;
long long data[40];
struct node
{
    long long n;
    int cnt;
    bool operator < (const node &aa) const {
        if (n != aa.n)
            return n < aa.n;
        return cnt < aa.cnt;
    }
}a[270000], b[270000];
void dfs(int index, int cnt, long long sum, int end) {
    if (index > end) {
        if(cnt) {
            a[++l1].n = -sum;
            a[l1].cnt = cnt;
        }
        return;
    }
    dfs(index + 1, cnt, sum, end);
    dfs(index + 1, cnt + 1, sum + data[index], end);
}
void dfs1(int index, int cnt, long long sum, int end) {
    if (index > end) {
        if(cnt) {
            b[++l2].n = sum; b[l2].cnt = cnt;
        }
        return;
    }
    dfs1(index + 1, cnt, sum, end);
    dfs1(index + 1, cnt + 1, sum + data[index], end);
}
long long _abs(long long n) {
    return n >= 0 ? n : -n;
}
#define inf 0x7fffffffffffffffLL
int main() {
    int n, nn;
    while(scanf("%d", &n), n)
    {
        bool flag=false;
        for(int i = 1; i <= n; i++)
        {
            scanf("%I64d", &data[i]);
            if(data[i]==0)
                flag=true;
        }
        if(flag)
        {
            printf("0 1\n");
            continue;
        }
        if (n == 1) {
            printf("%I64d %d\n", _abs(data[1]), 1);
            continue;            
        }
        l1 = l2 = 0;
        nn = n/2;
        dfs(1, 0, 0, nn);//左邊取反,右邊不取反??好查找
        dfs1(nn+1, 0, 0 ,n);//咋不加1?因爲nn和n都比實際長度大1

        sort(a+1, a + l1+1);
        int LL = 1;
        for(int i =2 ;i <= l1; i++)
            if(a[i].n != a[i-1].n)
                a[++LL] = a[i];
        l1= LL;
        sort(b+1, b + l2+1);
        LL = 1;
        for(int i = 2; i<= l2;i++)
            if( b[i].n != b[i-1].n)
                b[++LL] = b[i];
        l2 = LL;
        ///////////////////////////////////////////
        long long ans = inf;
        int cnt;
        long long tmp;
        int i = 1;
        for (int j = 1; j <= l2; j++)
        {
            while(i <= l1 && a[i].n < b[j].n) i++;
            if (i <= l1)
            {
                tmp = _abs(b[j].n - a[i].n);
                if (ans > tmp || (ans == tmp && cnt > b[j].cnt + a[i].cnt))
                {
                    ans = tmp;
                    cnt = b[j].cnt + a[i].cnt;
                }
            }
            if (i > 1)
            {
                tmp = _abs(b[j].n - a[i - 1].n);
                if (ans > tmp || (ans == tmp && cnt > b[j].cnt + a[i - 1].cnt))
                {
                    ans = tmp;
                    cnt = b[j].cnt + a[i - 1].cnt;
                }
            }
        }
        for(i = 1; i<= l1; i++)
        {
            tmp = _abs(a[i].n);
            if(ans > tmp || ((ans == tmp) && cnt >a[i].cnt))
            {
                ans = _abs(a[i].n);
                cnt = a[i].cnt;
            }
        }
        for(i = 1; i<= l2; i++)
        {
            tmp = _abs(b[i].n);
            if(ans > tmp || ((ans == tmp) && cnt >b[i].cnt))
            {
                ans = tmp;
                cnt = b[i].cnt;
            }
        }
        //printf("i = %d ans = %I64d, cnt = %d\n",i, ans ,cnt);
        printf("%I64d %d\n", ans, cnt);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章