折半搜索 poj3977

来源:互联网 发布:mac上word文档丢失 编辑:程序博客网 时间:2024/05/06 15:20
// B subset#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<string.h>#include<map>using namespace std;#define ll long long #define MAX 1000000000000020ll ll__absolute(ll x){if (x < 0)return -x;return x;}int main(){int n;while (cin>>n&&n){ll arr[40];map<ll, int> sum;for (int i = 0; i <n; i++)cin >> arr[i];pair<ll, int> result(ll__absolute(arr[0]), 1);//先枚举其中的一半for (ll i = 0; i < (1 << n / 2); i++){ll sums = 0;int numn = 0;for (int j = 0; j < n / 2; j++) {if ((i >> j) & 1) {sums += arr[j];numn++;}}if (numn == 0)continue;map <ll, int> ::iterator it=sum.find(sums);if (it != sum.end()) {sum[sums] = min(it->second, numn);}else sum[sums] = numn;result = min(result, make_pair(ll__absolute(sums), numn));}//枚举另一半for (ll i = 0; i < (1 << (n - n / 2)); i++) {ll sums = 0;int numn = 0;for (int j = 0; j <(n - n / 2); j++) {if ((i >> j) & 1) {sums += arr[j + n / 2];numn++;}}if (numn == 0)continue;result = min(result, make_pair(ll__absolute(sums), numn));map<ll, int> ::iterator it = sum.lower_bound(-sums);if (it != sum.end()) {result = min(result, make_pair(ll__absolute(sums + it->first), numn + it->second));}if (it != sum.begin()) {it--;result = min(result, make_pair(ll__absolute(sums + it->first), numn + it->second));}}cout << ll__absolute(result.first) << ' ' << result.second << endl;}return 0;}