POJ 3977:Subset(折半枚举+二分)
【题目链接】 http://poj.org/problem?id=3977
【题目大意】
在n个数(n<36)中选取一些数,使得其和的绝对值最小.
【题解】
因为枚举所有数选或者不选,复杂度太高无法承受,
我们考虑减小枚举的范围,我们将前一半进行枚举,保存其子集和,
然后后一半枚举子集和取反在前一半中寻找最接近的,两部分相加用以更新答案。
【代码】
#include <cstdio>
#include <utility>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
const int N=40;
int n; LL a[N];
LL Abs(LL x){return x<0?-x:x;}
int main(){
while(scanf("%d",&n)&&n){
for(int i=0;i<n;i++)scanf("%lld",&a[i]);
map<LL,int> M;
map<LL,int>::iterator it;
pair<LL,int> ans(Abs(a[0]),1);
for(int i=1;i<1<<(n/2);i++){
LL s=0; int cnt=0;
for(int j=0;j*2<n;j++){if((i>>j)&1)s+=a[j],cnt++;}
ans=min(ans,make_pair(Abs(s),cnt));
if(M[s])M[s]=min(M[s],cnt);
else M[s]=cnt;
}
for(int i=1;i<1<<(n-n/2);i++){
LL s=0; int cnt=0;
for(int j=0;j<(n-n/2);j++){
if((i>>j)&1)s+=a[j+n/2],cnt++;
}ans=min(ans,make_pair(Abs(s),cnt));
it=M.lower_bound(-s);
if(it!=M.end())ans=min(ans,make_pair(Abs(s+it->first),cnt+it->second));
if(it!=M.begin()){
it--;
ans=min(ans,make_pair(Abs(s+it->first),cnt+it->second));
}
}printf("%lld %d\n",ans.first,ans.second);
}return 0;
}
POJ 3977:Subset(折半枚举+二分)的更多相关文章
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- POJ 3977 - subset - 折半枚举
2017-08-01 21:45:19 writer:pprp 题目: • POJ 3977• 给定n个数,求一个子集(非空)• 使得子集内元素和的绝对值最小• n ≤ 35 AC代码如下:(难点:枚 ...
- [poj] 3977 Subset || 折半搜索MITM
原题 给定N个整数组成的数列(N<=35),从中选出一个子集,使得这个子集的所有元素的值的和的绝对值最小,如果有多组数据满足的话,选择子集元素最少的那个. n<=35,所以双向dfs的O( ...
- POJ 3977 Subset | 折半搜索
题目: 给出一个整数集合,求出非空子集中元素和绝对值最小是多少(元素个数尽量少) 题解: 分成两半 爆搜每一半,用map维护前一半的值 每搜出后一半的一个值就去map里找和他和绝对值最小的更新答案 # ...
- CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。
1514: Packs Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 61 Solved: 4[Submit][Status][Web Board] ...
- poj 3977 Subset(折半枚举+二进制枚举+二分)
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 5721 Accepted: 1083 Descripti ...
- POJ 3977 Subset
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 3161 Accepted: 564 Descriptio ...
- Subset POJ - 3977(折半枚举+二分查找)
题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...
- 【折半枚举+二分】POJ 3977 Subset
题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...
随机推荐
- 【转载】Unity3D研究院之与根据动态的两个轨迹点绘制面详解
大家应该知道3D世界中任何的面都是由三角形绘制完成的,因为任何无规则的集合图形都可以由三角形来组成.比如四边形,无论是正四边形还是无规则四边形都可以由两个三角形拼接而成.结合本文的标题大家仔细想想,如 ...
- 【java并发编程实战】第二章:对象的共享
1.重要的属性 可见性,不变性,原子性 1.1可见性 当一个线程修改某个对象状态的时候,我们希望其他线程也能看到发生后的变化. 在没有同步的情况下,编译器和处理器会对代码的执行顺序进行重排.以提高效率 ...
- Class对象和反射
1.class对象在java中一切都是对象,从某种意义上,java中的对象可以分为:实例对象和Class对象.实例对象通过new关键得到,那么Class对象呢?Class对象无法通过new关键字获取, ...
- OpenCV_1.0安装包下载
OpenCV_1.0安装包下载 点击下载
- vue 自定义过度组件用法
HTML: <div id="example-1"> <button @click="show = !show"> Toggle ren ...
- linux备忘录-bash
知识点 环境变量 HOME PATH MAIL SHELL RANDOM // 0~32767的随机数 declare -i number=$RANDOM*10/32768 //0-9的随机数 HIS ...
- 团队冲刺Alpha(八)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- winform中key读取修改
根据key name的名称读取value-----读取使用ConfigurationManager.AppSettings读取容易没读取到根目录中的key public string GetXml(s ...
- <a></a>的href属性失效
<a href="javascript:void(0);" class="close">关闭</a>
- css 实现高斯模糊
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...