博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[poj] 3977 Subset || 折半搜索MITM
阅读量:5320 次
发布时间:2019-06-14

本文共 1460 字,大约阅读时间需要 4 分钟。

给定N个整数组成的数列(N<=35),从中选出一个子集,使得这个子集的所有元素的值的和的绝对值最小,如果有多组数据满足的话,选择子集元素最少的那个。


n<=35,所以双向dfs的O(2^(n/2))可以直接解决问题。因为会爆空间,所以枚举前一半的二进制状态来完成dfs,并用map记录每个状态所用的个数,然后枚举后一半的状态在map中找第一个大于等于他的和第一个小于他的,比较这两个答案。

注:long long 没有自带的abs,并且在define里要多打括号,因为优先度……

#include
#include
#define abs(x) ((x)>0?(x):-(x))typedef long long ll;using namespace std;ll n,a[40],ans,sum;int cnt;map
mp;map
:: iterator qwq;ll read(){ ll ans=0,fu=1; char j=getchar(); for (;(j<'0' || j>'9') && j!='-';j=getchar()) ; if (j=='-') j=getchar(),fu=-1; for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0'; return ans*fu;}int main(){ while (~scanf("%lld",&n) && n) { mp.clear(); ans=0; cnt=0; for (int i=1;i<=n;i++) a[i]=read(); ans=abs(a[1]); cnt=1; for (int i=1,j,now,count;i<(1<<(n/2));i++) { sum=0; j=i; now=0; count=0; while (j) { if (j&1) sum+=a[now+1],count++; j>>=1; now++; } if (abs(sum)
>=1; now++; } if (abs(sum)
first; nw=abs(nw); if (nw
second+count; } else if (nw==ans) cnt=min(cnt,qwq->second+count); } if (qwq!=mp.begin()) { qwq--; nw=sum+qwq->first; nw=abs(nw); if (nw
second+count; } else if (nw==ans) cnt=min(cnt,qwq->second+count); } } printf("%lld %d\n",ans,cnt); } return 0;}

转载于:https://www.cnblogs.com/mrha/p/8017975.html

你可能感兴趣的文章
HTTPS连接前的几毫秒发生了什么?
查看>>
The Willpower Instinct
查看>>
scrapy 手动编写模板
查看>>
【java】对象序列化Serializable、transient
查看>>
05.数组和字典
查看>>
数组中 == 比较运算符注意事项
查看>>
应用三:Vue之混入(mixin)与全局混入
查看>>
Android开发环境的搭建
查看>>
STS启动springboot项目,加载不了resources下的配置文件的问题
查看>>
牛客多校第四场 F Beautiful Garden
查看>>
lib和dll的认识
查看>>
Centos7.4下安装Redis5.0
查看>>
WINFORM窗体里使用网页控件的一些办法
查看>>
9.16 基于form表单的文件上传实现 ContextType
查看>>
获取数据库表中自增长最新的id
查看>>
配置Codis-FE(管理界面)
查看>>
高并发高可用服务设计思路
查看>>
windows系统下安装 node.js (node.js安装及环境配置)
查看>>
帮助理解Matlab梯度函数gradient
查看>>
3D游戏的角色移动
查看>>