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. 异步编程 In .NET(转载)

    概述 在之前写的一篇关于async和await的前世今生的文章之后,大家似乎在async和await提高网站处理能力方面还有一些疑问,博客园本身也做了不少的尝试.今天我们再来回答一下这个问题,同时我们 ...

  2. win xp 环境变量PATH默认值

    %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem

  3. mysql-8 alter命令

    当我们需要修改数据表名或者修改数据表字段时,就需要用到Mysql alter命令. 查看表结构: -- 以下2个命令是通用的 show columns from test_alter_tbl; des ...

  4. istio 配置https gateway

    沒有親手實驗,参考官方文档:  https://istio.io/docs/tasks/traffic-management/secure-ingress/

  5. 简单神经网络TensorFlow实现

    学习TensorFlow笔记 import tensorflow as tf #定义变量 #Variable 定义张量及shape w1= tf.Variable(tf.random_normal([ ...

  6. [maven] 实战笔记 - 构建、打包和安装maven

    ① 手工构建自己的maven项目 Maven 项目的核心是 pom.xml.POM (Project Object Model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明项目依赖等 ...

  7. 20165233 Java第八、十五章学习总结

    20165233 2017-2018-2 <Java程序设计>第六周学习总结 教材学习内容总结 ch08 基础:String类 重点:StringTokenizer类.Scanner类:获 ...

  8. python爬虫 发送定时气象预报

    python爬取天气情况 下面为示例代码: from urllib.request import urlopen from bs4 import BeautifulSoup from urllib.e ...

  9. How To Manually Install Oracle Java on Ubuntu

    Introduction Java is a programming technology originally developed by Sun Microsystems and later acq ...

  10. Source命令及脚本的执行方式

    [Source命令及脚本的执行方式] source filename 与 sh filename 及./filename执行脚本的区别在那里呢? 1.当shell脚本具有可执行权限时,用sh file ...