Subset
Time Limit: 30000MS        Memory Limit: 65536K
Total Submissions: 6754        Accepted: 1277

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

Source
Seventh ACM Egyptian National Programming Contest

题解:给出n个数,让你取出一个子集,使子集和的绝对值最小,如果有多个构成相同绝对值的方案,取子集个数最小的

求最小绝对值和最小大小

题解:数据范围可以猜出是折半枚举,前一半的数可以在len×2^(n/2)内求出,然后再暴力枚举后一半的和sum,在前一半的所有答案中找出与-sum最相近的两个数,对于sum所产生的贡献,答案肯定只会由这两个数+sum影响。当然还要考虑空集的情况,也就是只取前面或者只取后面

代码如下:

#include<map>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson ch[x][0]
#define rson ch[x][1]
#define hi puts("hi!");
#define int long long
#define mp make_pair
#define pii pair<int,int>
using namespace std; int n,len1,len2,a[];
map<int,int> m; long long absl(long long x)
{
return x>0ll?x:-x;
} signed main()
{
while(~ scanf("%lld",&n)&&n)
{
m.clear();
pii ans=mp(1e18,0ll);
for(int i=;i<n;i++) scanf("%lld",&a[i]);
len1=n/;
len2=n-len1;
for(int i=;i<<<len1;i++)
{
int cnt=,sum=;
for(int j=;j<len1;j++)
{
if(i&(<<j))
{
cnt++;
sum+=a[j];
}
}
if(!m.count(sum)||m[sum]>cnt) m[sum]=cnt;
if(ans>mp(absl(sum),cnt)) ans=mp(absl(sum),cnt);
}
for(int i=;i<<<len2;i++)
{
int cnt=,sum=;
for(int j=;j<len2;j++)
{
if(i&(<<j))
{
cnt++;
sum+=a[len1+j];
}
}
if(ans>mp(absl(sum),cnt)) ans=mp(absl(sum),cnt);
map<long long,long long>::iterator it=m.lower_bound(-sum);
if(it!=m.end())
{
if(ans>mp(absl(sum+it->first),cnt+it->second))
{
ans=mp(absl(sum+it->first),cnt+it->second);
}
}
if(it!=m.begin()) it--;
if(it!=m.end())
{
if(ans>mp(absl(sum+it->first),cnt+it->second))
{
ans=mp(absl(sum+it->first),cnt+it->second);
}
}
}
printf("%lld %lld\n",ans.first,ans.second);
}
}

POJ 3977 Subset(折半枚举+二分)的更多相关文章

  1. POJ 3977 - subset - 折半枚举

    2017-08-01 21:45:19 writer:pprp 题目: • POJ 3977• 给定n个数,求一个子集(非空)• 使得子集内元素和的绝对值最小• n ≤ 35 AC代码如下:(难点:枚 ...

  2. [poj] 3977 Subset || 折半搜索MITM

    原题 给定N个整数组成的数列(N<=35),从中选出一个子集,使得这个子集的所有元素的值的和的绝对值最小,如果有多组数据满足的话,选择子集元素最少的那个. n<=35,所以双向dfs的O( ...

  3. POJ 3977 Subset | 折半搜索

    题目: 给出一个整数集合,求出非空子集中元素和绝对值最小是多少(元素个数尽量少) 题解: 分成两半 爆搜每一半,用map维护前一半的值 每搜出后一半的一个值就去map里找和他和绝对值最小的更新答案 # ...

  4. CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。

    1514: Packs Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 61  Solved: 4[Submit][Status][Web Board] ...

  5. poj 3977 Subset(折半枚举+二进制枚举+二分)

    Subset Time Limit: 30000MS   Memory Limit: 65536K Total Submissions: 5721   Accepted: 1083 Descripti ...

  6. POJ 3977 Subset

    Subset Time Limit: 30000MS   Memory Limit: 65536K Total Submissions: 3161   Accepted: 564 Descriptio ...

  7. POJ 3977:Subset(折半枚举+二分)

    [题目链接] http://poj.org/problem?id=3977 [题目大意] 在n个数(n<36)中选取一些数,使得其和的绝对值最小. [题解] 因为枚举所有数选或者不选,复杂度太高 ...

  8. Subset POJ - 3977(折半枚举+二分查找)

    题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...

  9. 【折半枚举+二分】POJ 3977 Subset

    题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...

随机推荐

  1. 黄聪:win7 64位系统PS、AI、PSD缩略图预览补丁

    MysticThumbs支持Windows 7 / Vista / XP,32位和64位.除了预览PSD以外,还支持DDS.SGI缩略图显示. Mystic Thumbs是一款用来支持win7 64位 ...

  2. JVM参数之-XX:+HeapDumpOnOutOfMemoryError(导出内存溢出的堆信息(hprof文件))

    当出现HeapDumpOnOutOfMemoryError错误时,我们需要分析原因,下面的程序就是模拟这个错误并导出dump文件,好让你分析 GcTest.java package gc; publi ...

  3. mysql-6正则表达式

    mysql正则表达式 匹配的两种方式: 1.模糊匹配:like 2.正则表达式 正则表达式语法: 语法 说明 ^ 起始位置.如果设置了RegExp对象的Multiline属性,^也匹配'\n'或'\r ...

  4. ubuntu安装tushare

    sudo apt-get install python-pandas sudo pip install tushare

  5. 管理Linux服务器的用户和组(续篇)

    用户切换 新建用户 useradd命令的选项 设置用户口令 passwd命令的选项 chage命令 修改用户帐户 禁用和恢复用户帐户 禁用和恢复用户帐户- Passwd命令 禁用和恢复用户帐户-直接修 ...

  6. android.support.v7.internal.widget.ActionBarOverlayLayout Couldn't Be Initialized

    问题症状: Android Studio 1.2 (Build 141.1890965) 新建工程,自动build完成后,Layout Editor无法预览Layout文件,报错内容: Renderi ...

  7. django-渲染页面+locals

    from django.shortcuts import render, redirect from django.views import View from django.http import ...

  8. python xlwt操作excel

  9. python学习-day 1

    Python开发IDE(工具)Pycharm.eclipse1.循环while 条件 #循环体 #条件为真则执行 #条件为假则执行break用于退出所有循环continue用于退出当前循环 2.Pyc ...

  10. Spring IO Platform介绍

    为什么要用Spring IO Platform 今天无意间看到了一个关键词:"Spring IO Platform",第一直觉是不是有关于IO方面的框架或者包呢,查了一下,居然是为 ...