标签:
| 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