Subset

Time Limit: 30000MS Memory Limit: 65536K

Total Submissions: 5961 Accepted: 1129

Description

Given a list of N integers with absolute values no larger than 1015, find a non empty subset of these numbers which minimizes the absolute value of the sum of its elements. In case there are multiple subsets, choose the one with fewer elements.

Input

The input contains multiple data sets, the first line of each data set contains N <= 35, the number of elements, the next line contains N numbers no larger than 1015 in absolute value and separated by a single space. The input is terminated with N = 0

Output

For each data set in the input print two integers, the minimum absolute sum and the number of elements in the optimal subset.

Sample Input

1

10

3

20 100 -100

0

Sample Output

10 1

0 2


解题心得:

  1. 就是一个双向搜索,要求的是选择出来的元素的总和的绝对值最小,按照双向搜索的思路去做就可以了。但是要注意的一点是在二分搜索最相近的答案的时候可能从这个数的lower_bound产生的结果,或者lower_bound的位置-1产生绝对值最小的答案。

#include <algorithm>
#include <cstring>
#include <map>
#include <stdio.h>
using namespace std;
typedef long long ll;
const ll maxn = 45;
const ll MAX = 1e15; map <ll,ll> M;
pair <ll,ll> ans;
ll n,num[maxn]; ll Abs(ll x) {
if(x < 0)
return -x ;
return x;
} void init() {
M.clear();
ans = make_pair(MAX,MAX);
for(int i=0;i<n;i++) scanf("%lld",&num[i]);
} void get_sum(ll mid) {
ll cnt,sum;
for(ll i=1;i<(1<<mid);i++) {
cnt = sum = 0;
for(ll j=0;j<mid;j++) {
if(1&(i>>j)) {
sum += num[j];
cnt++;
}
}
ans = min(ans,make_pair(Abs(sum),cnt));
if(M[sum]) {
M[sum] = min(M[sum],cnt);
} else
M[sum] = cnt;
}
} void solve(ll mid) {
map<ll,ll> :: iterator iter;
for(ll i=1;i<(1<<(n-mid));i++) {
ll sum,cnt;
sum = cnt = 0;
for(int j=0;j<(n-mid);j++) {
if(1&(i>>j)) {
sum += num[mid+j];
cnt++;
}
}
ans = min(ans,make_pair(Abs(sum),cnt)); iter = M.lower_bound(-sum);
if(iter != M.end()) {
ans = min(ans,make_pair(Abs(iter->first+sum),cnt+iter->second));
}
if(iter != M.begin()) {
iter--;
ans = min(ans,make_pair(Abs(iter->first+sum),iter->second+cnt));
}
}
printf("%lld %lld\n",ans.first,ans.second);
} int main() {
while(scanf("%lld",&n) && n) {
init();
ll mid = n>>1;
get_sum(mid);
solve(mid);
}
return 0;
}

最新文章

  1. Rafy 框架 - 执行SQL或存储过程
  2. CSS布局 -- 圣杯布局 &amp; 双飞翼布局
  3. Cygwin的安装
  4. 仿IOS圆形下载进度条
  5. FindResource函数错误代码:1813-找不到映像文件中指定的资源类型 与LoadResource函数错误代码:1812-指定的映像文件不包含资源区域
  6. linux umask使用详解
  7. 【原创】C++链表如何像Python List一样支持多种数据类型
  8. undefined与null的区别---js
  9. 学习笔记_Filter小结(过滤器JavaWeb三大组件之一)
  10. C语言栈的实现
  11. Tomcat6 Session建立机制简要
  12. javascript 回调, 单线程执行
  13. document.getElementById(&quot;searchForm&quot;).submit is not a function
  14. maven打包如何跳过测试
  15. TP5创建动态数据表
  16. STSdb数据库的实现使用类
  17. CentOS 6.5 手动rpm包安装gcc、g++
  18. mongoDB数据库插入数据时报错:db.collection is not a function
  19. java程序中加入@SuppressWarnings(&quot;serial&quot;)是什么意思?
  20. ubuntu下安装pdf编辑器Master PDF Editor

热门文章

  1. Spring文件上传Demo
  2. CSS3制作3D旋转视频展示区
  3. Programming for thread in Java
  4. Android打包混淆文件模板
  5. java中将数组、对象、Map、List转换成JSON数据
  6. git 因线上分支名重复导致无法拉取代码
  7. 爬虫技术框架——Heritrix
  8. mysql:数据库保存时间的类型——int和datetime的区别
  9. Gameplay Classes
  10. MySQL入门很简单: 11 mysql函数