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;
}

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

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

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

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

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

    SubsetTime Limit: 30000MS        Memory Limit: 65536KTotal Submissions: 6754        Accepted: 1277 D ...

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

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

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

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

  7. POJ 3977 Subset | 折半搜索

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

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

    题意:有一个N(N <= 35)个数的集合,每个数的绝对值小于等于1015,找一个非空子集,使该子集中所有元素的和的绝对值最小,若有多个,则输出个数最小的那个. 分析: 1.将集合中的元素分成两 ...

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

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

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

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

随机推荐

  1. ASP.NET MVC 音乐商店 - 5. 通过支架创建编辑表单

    在上一章,我们已经从数据库获取数据,然后显示出来,这一章,我们将允许编辑数据. 创建 StoreManagerController 控制器 我们将要创建称为 StoreManager 的控制器,对于这 ...

  2. thinkphp的find()方法获取结果

    find方法返回的是一行记录,结果是一个数组,数组的key和sql中的field相对应,假设: $res=$model->find(filed="a,b,c"); 获取结果中 ...

  3. git 分之合并和冲突解决

    Git 分支管理和冲突解决 创建分支 git branch 没有参数,显示本地版本库中所有的本地分支名称. 当前检出分支的前面会有星号. git branch newname 在当前检出分支上新建分支 ...

  4. Android 编辑框(EditText)属性学习

    EditText的属性很多,这里介绍几个:android:hint="请输入数字!"//设置显示在空间上的提示信息android:numeric="integer&quo ...

  5. Poj(1125),Floyd,

    题目链接:http://poj.org/problem?id=1125 多源点最短路中的,最长路的,最短路. 看到这里就懵逼了,解释一下,找到一个源点,使得路最短,(遍历源点),路最短怎么求呢? 就是 ...

  6. SVN知识集合

    1. 如果某个项目之前保存了A仓库的信息,无法切换到B仓库(通过AnkhSVN或者VisualSVN),可以先在本地去除版本控制(用TortoiseSVN),然后导出B仓库信息(用TortoiseSV ...

  7. javascript原生API总结

    一.查找: getElementById() 方法返回带有指定 ID 的元素(唯一): getElementsByTagName() 返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组). ...

  8. SpringBoot发布WAR启动报错:Error assembling WAR: webxml attribute is required

    Spring Boot发布war包流程: 1.修改web model的pom.xml <packaging>war</packaging> SpringBoot默认发布的都是j ...

  9. 使用nsis开发自定义安装包使用心得,以及遇到坑

    因为新公司需要开发pc应用的自定义安装包,开始时候计划使用nsis开发,论坛上面有很多不错的例子,而且完成度很强, 随便拿来修改使用,但是后续的开发过程中遇到的问题就逐个出现. 首先说一下nsis的优 ...

  10. HDU 2047 EOF牛肉串

    水到不想整理,线性DP #include <algorithm> #include <iostream> #include <cstring> #include & ...