题目链接:https://vjudge.net/problem/POJ-3977

题意:给一个大小<=35的集合,找一个非空子集合,使得子集合元素和的绝对值最小,如果有多个这样的集合,找元素个数最少的。

思路:显然,可以用折半搜索,分别枚举一半,最大是2的18次方,复杂度能够满足。因为集合非空,枚举时考虑只在前一半选和只在后一半选的情况。对于前一半后一半都选的情况,把前一半的结果存下来,排序,枚举后一半的时候在前一半里二分查找最合适的即可。

思路不难,实现有很多细节,最开始用dfs写得一直wa,改成二进制循环才A。

AC代码:

#include<cstdio>
#include<algorithm>
#include<map>
using namespace std; typedef long long LL;
typedef pair<LL,int> PLI;
const LL inf1=1e17;
const int inf2=0x3f3f3f3f;
int n,m,cnt,ans2;
LL a[],ans1;
PLI b[];
map<LL,int> mp; LL absLL(LL x){
return x>=?x:-x;
} int main(){
while(scanf("%d",&n),n){
mp.clear();
cnt=;
ans1=inf1;
ans2=inf2;
for(int i=;i<=n;++i)
scanf("%lld",&a[i]);
m=n/;
for(int i=;i<(<<m);++i){
LL res1=;
int res2=;
for(int j=;j<m;++j)
if((i>>j)&){
res1+=a[j+];
++res2;
}
if(absLL(res1)<ans1){
ans1=absLL(res1),ans2=res2;
}
else if(absLL(res1)==ans1){
ans2=min(ans2,res2);
}
if(mp.count(res1)){
int tmp=mp[res1];
b[tmp].second=min(b[tmp].second,res2);
}
else{
b[++cnt].first=res1,b[cnt].second=res2;
mp[res1]=cnt;
}
}
sort(b+,b+cnt+);
for(int i=;i<(<<(n-m));++i){
LL res1=;
int res2=;
for(int j=;j<(n-m);++j)
if((i>>j)&){
res1+=a[j++m];
++res2;
}
if(absLL(res1)<ans1){
ans1=absLL(res1),ans2=res2;
}
else if(absLL(res1)==ans1){
ans2=min(ans2,res2);
}
LL tmp=-res1;
int l=,r=cnt,mid;
while(l<=r){
mid=(l+r)>>;
if(b[mid].first<=tmp) l=mid+;
else r=mid-;
}
if(r>){
if(absLL(b[r].first+res1)<ans1){
ans1=absLL(b[r].first+res1);
ans2=b[r].second+res2;
}
else if(absLL(b[r].first+res1)==ans1){
ans2=min(ans2,b[r].second+res2);
}
}
if(r+<=cnt){
if(absLL(b[r+].first+res1)<ans1){
ans1=absLL(b[r+].first+res1);
ans2=b[r+].second+res2;
}
else if(absLL(b[r+].first+res1)==ans1){
ans2=min(ans2,b[r+].second+res2);
}
}
}
printf("%lld %d\n",ans1,ans2);
}
return ;
}

poj3977(折半枚举+二分查找)的更多相关文章

  1. CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。

    1514: Packs Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 61  Solved: 4[Submit][Status][Web Board] ...

  2. Subset POJ - 3977(折半枚举+二分查找)

    题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...

  3. Subset---poj3977(折半枚举+二分查找)

    题目链接:http://poj.org/problem?id=3977 给你n个数,找到一个子集,使得这个子集的和的绝对值是最小的,如果有多种情况,输出子集个数最少的: n<=35,|a[i]| ...

  4. POJ 2549 Sumsets(折半枚举+二分)

    Sumsets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11946   Accepted: 3299 Descript ...

  5. 【折半枚举+二分】POJ 3977 Subset

    题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...

  6. POJ 3977 Subset(折半枚举+二分)

    SubsetTime Limit: 30000MS        Memory Limit: 65536KTotal Submissions: 6754        Accepted: 1277 D ...

  7. Codeforces H. Prime Gift(折半枚举二分)

    题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...

  8. POJ 2785 4 Values whose Sum is 0(折半枚举+二分)

    4 Values whose Sum is 0 Time Limit: 15000MS   Memory Limit: 228000K Total Submissions: 25675   Accep ...

  9. POJ 3977:Subset(折半枚举+二分)

    [题目链接] http://poj.org/problem?id=3977 [题目大意] 在n个数(n<36)中选取一些数,使得其和的绝对值最小. [题解] 因为枚举所有数选或者不选,复杂度太高 ...

随机推荐

  1. 【题解】[NOIP模拟题]我要的幸福-C++

    题目Description我要的幸福(happiness)幸福/我要的幸福/渐渐清楚/梦想/理想/幻想/狂想/妄想/我只想坚持每一步/该走的方向/就算一路上/偶尔会沮丧/生活是自己/选择的衣裳/幸福/ ...

  2. 022_STM32中断优先级分组解析

    (0)STM32有十六个优先级 (一)STM32分组为:组0-4 (二)分组配置在寄存器SCB->AIRCR中: (三)解析第二点 1. 组0就是4位都用来设置成响应优先级,2^4=16位都是响 ...

  3. ckeditor粘贴word图片自动上传功能

    由于工作需要必须将word文档内容粘贴到编辑器中使用 但发现word中的图片粘贴后变成了file:///xxxx.jpg这种内容,如果上传到服务器后其他人也访问不了,网上找了很多编辑器发现没有一个能直 ...

  4. Comet OJ - Contest #2 (D 错综的光影所迷惑的思念是) 容斥计数

    题意:给定一颗 $n$ 个节点的树,定义 $dis(x,y)$ 为树上点 $x$ 到 $y$ 的路径经过的边数. 定义一个点集 $S$ 的 $f(S)$ 为 $f(S)=max\left \{dis( ...

  5. 最小生成树&&次小生成树

    对于一个边上具有权值的图来说,其边权值和最小的生成树叫做图G的最小生成树 求无向图最小生成树主要有prim和kruskal两种算法 1.prim 将点集V分成Va和Vb两部分,Va为已经连入生成树的点 ...

  6. 1~100卡特兰数(存一下hhhh)

    1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845 35357670 129644790 477638700 ...

  7. UVALive 4394 String painter ——(区间DP)

    其实这个dp过程有点似懂非懂...代码如下: #include <stdio.h> #include <algorithm> #include <string.h> ...

  8. Java中的集合Collection

    集合是什么? Java集合类存放于 java.util 包中,是一个用来存放对象的容器. 注意:①.集合只能存放对象.比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类 ...

  9. powerdesigner导出rtf

    报告--reports--新建reports--reports template选择None 从左侧的Available items 拖动 需要导出的item到右侧 右侧的每一个item右键 可以设置 ...

  10. 在Winform中屏蔽UnityWebPlayer的右键以及自带Logo解决方案整理

    根据项目的需要,对已经完成的Unity三维模型以及游戏要使用Winform进行包装,也就是使用Winform做一层外壳.因此在展示Unity的时候使用到了UnityWebPlayer这个插件,对于此插 ...