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 ...
随机推荐
- Zeppelin interperter 模式设置总结图解2
该配置是在zeppelin的Interpreter的后台配置文件:conf/Interpreter.json spark Interpreter的模块定义那里.特别感谢开发团队组长大神的提示,深入挖掘 ...
- 【CodeBase】PHP打印所有用户自定义常量
print_r(get_defined_constants(true)['user']);
- js 判断function是否存在
function myFunction(){ }//方法一 if(typeof(myFunction) == 'function'){ //function }else{ //undefined }/ ...
- McNay Art Museum【McNay艺术博物馆】
McNay Art Museum When I was 17, I read a magazine artice about a museum called the McNay, once the h ...
- POJ 3977 折半枚举
链接: http://poj.org/problem?id=3977 题意: 给你n个数,n最大35,让你从中选几个数,不能选0个,使它们和的绝对值最小,如果有一样的,取个数最小的 思路: 子集个数共 ...
- Matplotlib 图表的基本参数设置
1.图名,图例,轴标签,轴边界,轴刻度,轴刻度标签 # 图名,图例,轴标签,轴边界,轴刻度,轴刻度标签等 df = pd.DataFrame(np.random.rand(10,2),columns= ...
- POJ:2377-Bad Cowtractors
传送门:http://poj.org/problem?id=2377 Bad Cowtractors Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- laravel5.5路由使用name的好处
使用name的好处 辅助函数 route 可以用于为指定路由生成 URL.命名路由生成的 URL 不与路由上定义的 URL 相耦合.因此,就算路由的 URL 有任何更改,都不需要对 route 函数调 ...
- shell脚本递归删除空文件夹
有时我们需要递归删除空文件夹,网上找了一下,没有发现比较好的脚本,于是自己动手写了一个 脚本 #!/bin/bash # author: 十年后的卢哥哥(http://www.cnblogs.com/ ...
- Windows下安装PHP及开发环境配置
一.Apache 因为Apache官网只提供源代码,如果要使用必须得自己编译,这里我选择第三方安装包Apache Lounge. 1. 进入Apachelounge官方下载地址:http://www. ...