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. iOS开发之Objective-c的AES256加密和解密算法的实现

    原文:http://www.lidaren.com/archives/1470 高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法. 以下实现 ...

  2. RDF类型报表-PDF中文乱码

    在Oracle R12中,遇到了客户一张客户化的报表: 报表的输出格式是布局在RDF文件(非RTF)中,在并发请求输出时,PDF会出现中文乱码,而HTML和excel显示正常: 根据资料: 查看$OA ...

  3. Java—多态

    多态——对象的多种形态(继承是多态实现的基础) 引用多态:父类的引用可以指向本类的对象:父类的引用可以指向子类的对象 方法多态:创建本类对象时,调用的方法为本类方法:创建子类对象时,调用的方法为子类重 ...

  4. 用HttpSessionListener统计在线用户或做账号在线人数管理

    使用HttpSessionListener接口可监听session的创建和失效 session是在用户第一次访问页面时创建 在session超时或调用request.getSession().inva ...

  5. python生成url测试用例

    generate_url.py #!/usr/bin/env python import random import os, sys channels = [ \ "BTV2", ...

  6. java之Socket传递图片

    客户端: package client; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ...

  7. Description Resource Path Location Type Java compiler level does not match the version of the installed Java project facet Unknown Faceted Project Problem (Java Version Mismatch)

    project 编译问题,需要三处的jdk版本要保持一致,才能编译通过. 1.在项目上右键properties->project Facets->修改右侧的version  保持一致 2. ...

  8. SAP成都研究院Sunshine: 我的C4C实习感受和保研之路

    今天的文章来自SAP成都一位实习生,曾经和Jerry同在C4C成都开发团队一起工作过.在Sunshine最后一个工作日里,Jerry和Sunshine一起吃饭的时候,她曾经聊到接下来的保研打算和将来工 ...

  9. HTML入门1—HTML基础学习

    html文档结构 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  10. SIP MGCP和H323的区别

    在Windows中内置的NetMeeting就是典型的H.323协议客户端,而比较常见的SIP系统是微软开发的MSN Messenger系统.首先,由用户A向SIP服务器发出呼叫请求,请求的信息包含自 ...