POJ 3977 Subset | 折半搜索
题目:
给出一个整数集合,求出非空子集中元素和绝对值最小是多少(元素个数尽量少)
题解:
分成两半
爆搜每一半,用map维护前一半的值
每搜出后一半的一个值就去map里找和他和绝对值最小的更新答案
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
typedef long long ll;
using namespace std;
ll n,a[50],ans,tmp,ok;
map <ll,ll> mp;
map <ll,ll> :: iterator it;
ll Abs(ll x){ return x>0?x:-x;}
void DfsFront(ll step,ll state,ll val)
{
if (step>n/2)
{
it=mp.find(val);
if (it!=mp.end())
mp[val]=min(mp[val],state);
else
mp[val]=state;
if (Abs(val)<ans && state!=0)
ans=Abs(val),tmp=state;
if (Abs(val)==ans && state<tmp && state!=0)
tmp=state;
return ;
}
DfsFront(step+1,state,val);
DfsFront(step+1,state+1,val+a[step]);
}
void DfsBack(ll step,ll state,ll val)
{
if (step>n)
{
it=mp.lower_bound(-val);
ll w=it->first;
if (it!=mp.end() && Abs(val+w)<ans && it->second+state!=0)
ans=Abs(val+w),tmp=it->second+state;
if (it!=mp.end() && Abs(val+w)==ans && mp[w]+state<tmp && mp[w]+state!=0)
tmp=mp[w]+state;
if (it!=mp.begin()) it--;
if (it!=mp.end())
{
w=it->first;
if (Abs(val+w)<ans && state+it->second!=0)
ans=Abs(val+w),tmp=it->second+state;
if (Abs(val+w)==ans && it->second+state<tmp && it->second!=0)
tmp=it->second+state;
}
return ;
}
DfsBack(step+1,state,val);
DfsBack(step+1,state+1,val+a[step]);
}
int main()
{
while (scanf("%lld",&n)!=0,n)
{
mp.clear();
ans=mp[0]=0;
for (int i=1;i<=n;i++)
scanf("%lld",&a[i]),ans+=233+Abs(a[i]);
DfsFront(1,0,0);
DfsBack(n/2+1,0,0);
printf("%lld %lld\n",ans,tmp);
}
return 0;
}
POJ 3977 Subset | 折半搜索的更多相关文章
- [poj] 3977 Subset || 折半搜索MITM
原题 给定N个整数组成的数列(N<=35),从中选出一个子集,使得这个子集的所有元素的值的和的绝对值最小,如果有多组数据满足的话,选择子集元素最少的那个. n<=35,所以双向dfs的O( ...
- POJ 3977 - subset - 折半枚举
2017-08-01 21:45:19 writer:pprp 题目: • POJ 3977• 给定n个数,求一个子集(非空)• 使得子集内元素和的绝对值最小• n ≤ 35 AC代码如下:(难点:枚 ...
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- poj 3977 Subset(折半枚举+二进制枚举+二分)
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 5721 Accepted: 1083 Descripti ...
- 【折半枚举+二分】POJ 3977 Subset
题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...
- POJ - 3977 Subset(二分+折半枚举)
题意:有一个N(N <= 35)个数的集合,每个数的绝对值小于等于1015,找一个非空子集,使该子集中所有元素的和的绝对值最小,若有多个,则输出个数最小的那个. 分析: 1.将集合中的元素分成两 ...
- POJ 3977 Subset
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 3161 Accepted: 564 Descriptio ...
- POJ3977:Subset——题解(三分+折半搜索)
http://poj.org/problem?id=3977 题目大意:有一堆数,取出一些数,记他们和的绝对值为w,取的个数为n,求在w最小的情况下,n最小,并输出w,n. ————————————— ...
- bzoj2679: [Usaco2012 Open]Balanced Cow Subsets(折半搜索)
2679: [Usaco2012 Open]Balanced Cow Subsets Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 462 Solv ...
随机推荐
- docker swarm使用keepalived+haproxy搭建基于percona-xtradb-cluster方案的高可用mysql集群
一.部署环境 序号 hostname ip 备注 1 manager107 10.0.3.107 centos7;3.10.0-957.1.3.el7.x86_64 2 worker68 10.0.3 ...
- oracle之bitmap索引
oracle常见的索引是BTree索引和Bitmap索引. BTree索引特点: 默认索引 适合大量增删改查 不能用or操作符 适合高基数的列(即唯一值多) 创建sql:create index li ...
- Python生成器、装饰器
## 生成器 - 生成器是用来创建Python序列的一个对象 - 通常生成器是为迭代器产生数据的 - 例如range()函数就是一个生成器 - 每次迭代生成器时,它都会记录上一次调用的位置,并返回下一 ...
- 柱状图多系列php动态实现(ec)
<?php require_once 'data.php'; $arr1=$a->sum('answer','ask_id=1'); $arr2=$a->sum('answer',' ...
- Django项目发布到Apache2.4配置mod_wsgi,解决遭遇的各种坑。
环境: Apache2.4 32bit Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:05:16) [MSC v.1915 32 bit (Inte ...
- [CodeForces948B]Primal Sport(数论)
Description 题目链接 Solution 设f(x)为x的最大质因子 那么由题意易得\(X_1\)的范围在\([X_2-f(X_2)+1,X2]\) 同理\(X_0\)的范围在\([X_1- ...
- 笔记-python-standard library-26.4 unittest
笔记-python-standard library-26.4 unittest 1. unittest source code:Lib/unittest/__init__.py 它是pyt ...
- TouTiao开源项目 分析笔记7 加载数据的过程
1.以新闻页中的段子数据显示为例 1.1.首先执行InitApp==>SplashActivity. 因为在AndroidManifest.xml中定义了一个<intent-filter& ...
- react基本知识点合集
妹子UI里面有React的相关组件与用法:http://amazeui.org/react/components React官方网站:https://facebook.github.io/react/ ...
- 从事IT业一个8年老兵转行前的自我总结1——初爻
现在,本人已离开这个呆了8年的软件行业了.回想自己从半路出家,从实施开始做起,最终在一家外企做项目经理PM结束了自己的软件职业生涯.从一张白纸的自学开始,做过项目实施,客户培训,拿过需求,开发,架构设 ...