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 ...
随机推荐
- BeanUtils工具的实现
BeanUtils工具的实现 自定义一个将数据映射到类里的方法 方法一: package utils; import java.lang.reflect.Field; import java.lang ...
- Target runtime Apache Tomcat v8.5 is not defined.
Target runtime Apache Tomcat v8.5(或者其它版本) is not defined. 这个错误通常是在从文件夹中导入别人的项目的时候发生,因为 在 .setting 中有 ...
- php-5.6.26源代码 - opcode执行
文件 php-5.6.26/Zend/zend_vm_execute.h ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS ...
- PHP 日期处理函数 date() 、mktime()
一.前言 php是世界上最好的语言! 二.介绍 mktime()函数获取当周\当天\当月 /** * 微程-日期工具函数 week: 当周 day: 当天 month: 当月 * @author 狗蛋 ...
- laravel通过make auth实现手机号登录
首先按照Laravel的教程,安装认证系统. php artisan make:auth php artisan migrate laravel已经安装完成认证系统,默认注册和登录都是用邮箱. 如果想 ...
- PLC状态机编程第六篇-优化PLC程序生成
还记得第一篇博客中,我们在状态机中手写上升沿来处理有别于传统的一键启停程序,那个手写的上升沿就是优化手段.stateflow状态机是带事件的,事件本身支持上升沿和下降沿等事件,在这里,如果我们选择用事 ...
- poj 1759 二分搜索
题意:N个等差数列,初项X_i,末项Y_i,公差Z_i,求出现奇数次的数? 思路: 因为只有一个数出现的次数为奇数个 假设 第二个数字的个数为 奇数个,其余全部都是偶数个 ,累计出现的次数 a1偶数 ...
- Servlet HttpRequest 中【getAttribute】和【getParameter】的区别
1.获取的值不同 getAttribute表示从request范围取得设置的属性,必须要通过setAttribute设置属性,才能通过getAttribute取得.设置和取得的值都是Object类型. ...
- PHP.21-商品信息管理
商品信息管理 在线增删改查和图片信息管理 主要技术:文件上传.图片缩放.数据库基本操作 思路: 1.设计并创建数据库 库名:demodb 表名:goods 编号(id) 名称(name) 商品类型(t ...
- PHP.18-图片等比例缩放
图片等比例缩放 自定义函数ImageUpdateSize($pricname, $maxx, $maxy, $pre) 1.$pricname:被缩放的图片源(路径):2.$maxx,$maxy:缩放 ...