标签:
Time Limit: 30000MS | Memory Limit: 65536K | |
Total Submissions: 3161 | Accepted: 564 |
Description
Input
Output
Sample Input
1 10 3 20 100 -100 0
Sample Output
10 1 0 2
Source
#include <cstdio> #include <map> #define ll long long using namespace std; int n; ll a[40]; ll ll_abs(ll x) { return x >= 0 ? x : -x; } void solve() { map<ll, int> mp; map<ll, int>::iterator it; pair<ll, int> res(ll_abs(a[0]), 1); //初始化结果为第一个元素 for(int i = 1; i < 1<<(n/2); ++i){ //枚举区间为[1, 2^n),当i为0时,子集为空 ll sum = 0; int num = 0; for(int j = 0; j < n/2; ++j){ //按位枚举 if((i>>j)&1){ sum += a[j]; ++num; } } res = min(res, make_pair(ll_abs(sum), num)); //子集的元素只取自于A it = mp.find(sum); if(it != mp.end()) it->second = min(it->second, num); else mp[sum] = num; } for(int i = 1; i < 1<<(n-n/2); ++i){ ll sum = 0; int num = 0; for(int j = 0; j < n-n/2; ++j){ if((i>>j)&1){ sum += a[n/2+j]; ++num; } } res = min(res, make_pair(ll_abs(sum), num)); //子集的元素只取自于B it = mp.lower_bound(-sum); //查找与-sum最相近的值 if(it != mp.end()) //可能在该位置 res = min(res, make_pair(ll_abs(it->first+sum), it->second+num)); if(it != mp.begin()){ //可能在该位置的前一个位置 --it; res = min(res, make_pair(ll_abs(it->first+sum), it->second+num)); } } printf("%I64d %d\n", res.first, res.second); } int main() { while(scanf("%d", &n), n){ for(int i = 0; i < n; ++i) scanf("%I64d", &a[i]); solve(); } return 0; }
标签:
原文地址:http://www.cnblogs.com/inmoonlight/p/5766232.html