POJ 3977 Subset
| Time Limit: 30000MS | Memory Limit: 65536K | |
| Total Submissions: 3161 | Accepted: 564 |
Description
Input
Output
Sample Input
1
10
3
20 100 -100
0
Sample Output
10 1
0 2
Source
#include <cstdio>
#include <map>
#define ll long long
using namespace std; int n;
ll a[40]; ll ll_abs(ll x)
{
return x >= 0 ? x : -x;
} void solve()
{
map<ll, int> mp;
map<ll, int>::iterator it;
pair<ll, int> res(ll_abs(a[0]), 1); //初始化结果为第一个元素
for(int i = 1; i < 1<<(n/2); ++i){ //枚举区间为[1, 2^n),当i为0时,子集为空
ll sum = 0;
int num = 0;
for(int j = 0; j < n/2; ++j){ //按位枚举
if((i>>j)&1){
sum += a[j];
++num;
}
}
res = min(res, make_pair(ll_abs(sum), num)); //子集的元素只取自于A
it = mp.find(sum);
if(it != mp.end())
it->second = min(it->second, num);
else
mp[sum] = num;
}
for(int i = 1; i < 1<<(n-n/2); ++i){
ll sum = 0;
int num = 0;
for(int j = 0; j < n-n/2; ++j){
if((i>>j)&1){
sum += a[n/2+j];
++num;
}
}
res = min(res, make_pair(ll_abs(sum), num)); //子集的元素只取自于B
it = mp.lower_bound(-sum); //查找与-sum最相近的值
if(it != mp.end()) //可能在该位置
res = min(res, make_pair(ll_abs(it->first+sum), it->second+num));
if(it != mp.begin()){ //可能在该位置的前一个位置
--it;
res = min(res, make_pair(ll_abs(it->first+sum), it->second+num));
}
}
printf("%I64d %d\n", res.first, res.second);
} int main()
{
while(scanf("%d", &n), n){
for(int i = 0; i < n; ++i)
scanf("%I64d", &a[i]);
solve();
}
return 0;
}
POJ 3977 Subset的更多相关文章
- POJ 3977 - subset - 折半枚举
2017-08-01 21:45:19 writer:pprp 题目: • POJ 3977• 给定n个数,求一个子集(非空)• 使得子集内元素和的绝对值最小• n ≤ 35 AC代码如下:(难点:枚 ...
- poj 3977 Subset(折半枚举+二进制枚举+二分)
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 5721 Accepted: 1083 Descripti ...
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- 【折半枚举+二分】POJ 3977 Subset
题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...
- [poj] 3977 Subset || 折半搜索MITM
原题 给定N个整数组成的数列(N<=35),从中选出一个子集,使得这个子集的所有元素的值的和的绝对值最小,如果有多组数据满足的话,选择子集元素最少的那个. n<=35,所以双向dfs的O( ...
- POJ 3977 Subset | 折半搜索
题目: 给出一个整数集合,求出非空子集中元素和绝对值最小是多少(元素个数尽量少) 题解: 分成两半 爆搜每一半,用map维护前一半的值 每搜出后一半的一个值就去map里找和他和绝对值最小的更新答案 # ...
- POJ - 3977 Subset(二分+折半枚举)
题意:有一个N(N <= 35)个数的集合,每个数的绝对值小于等于1015,找一个非空子集,使该子集中所有元素的和的绝对值最小,若有多个,则输出个数最小的那个. 分析: 1.将集合中的元素分成两 ...
- POJ 3977:Subset(折半枚举+二分)
[题目链接] http://poj.org/problem?id=3977 [题目大意] 在n个数(n<36)中选取一些数,使得其和的绝对值最小. [题解] 因为枚举所有数选或者不选,复杂度太高 ...
- Subset POJ - 3977(折半枚举+二分查找)
题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...
随机推荐
- 时序列数据库武斗大会之TSDB名录 Part 2
[编者按] 刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融.通信以及Android手机操作系的开发,熟悉Linux及后台开发技术.曾参与翻译过<第一本Docker书> ...
- 天灵灵,地灵灵,但愿这个一定灵!!!python调用win32api,启动应用程序窗口
这个是逼到没办法,C#那一套,一点基本没有. 还好,网上找到例程,可以指定帐户启动进程,但愿可以摆脱WIN SERVICE启动产生的SESSION 0 隔离问题. 因为这个问题,以SERVICE启动的 ...
- 去掉eclipse的xml和js验证
一.XML Properties > Validation you have two options: 1- Configure Workspace Settings (disable the ...
- OSSEC - Agent端查看命令
命令:/opt/ossec/bin/agent_control -h注释:/opt/为安装目录 [root@redhat rules]# /opt/ossec/bin/agent_control -h ...
- 如何设计Java框架----一个简单的例子【翻译】
原文:http://www.programcreek.com/2011/09/how-to-design-a-java-framework/ 原文和翻译都只是参考,如有不对,欢迎指正. 你可能会好奇框 ...
- opencv 画延长线
hough变换可以让我们检测到直线,这在前面已有详解,对于车道检测,我们需要其到图像边界的延长线一遍之后数据帧分析. 以下代码帮助我们在opencv中画延长线,本来想用虚线表示延长线的,无奈参数调不好 ...
- 浅谈PHP自动化代码审计技术
原文出处: exploit 欢迎分享原创到伯乐头条 0×00 由于博客实在没什么可以更新的了,我就把目前做的事情总结一下,当做一篇博客,主要是谈一谈项目中所运用的一些技术.目前市面上有不少PHP的 ...
- <<c 和指针 >> 部分笔记。
最近竟然对指针有些迷惑了,分不清指针的指向.废话少说,复习.(下面内容来自<<c和指针>>) =指针 ==内存和地址 尽管一个字包含了4个字节,它仍然只有一个地址.至于是最左边 ...
- (六)CSS伪元素
CSS伪元素用于向某些选择器设置特殊效果. 伪元素的用法和伪类相似: selector:pseudo-element {property:value;} CSS类也可以与伪元素配合使用: select ...
- orzdba在5.6安装
前言:淘宝的orzdba查看MySQL服务器当前QPS,TPS很方便,但是不少人反应,在5.6原本好用的工具不好用了,频繁出现这样警告: Warning: Using a password on th ...