poj3977(折半枚举+二分查找)
题目链接: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(折半枚举+二分查找)的更多相关文章
- CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。
1514: Packs Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 61 Solved: 4[Submit][Status][Web Board] ...
- Subset POJ - 3977(折半枚举+二分查找)
题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...
- Subset---poj3977(折半枚举+二分查找)
题目链接:http://poj.org/problem?id=3977 给你n个数,找到一个子集,使得这个子集的和的绝对值是最小的,如果有多种情况,输出子集个数最少的: n<=35,|a[i]| ...
- POJ 2549 Sumsets(折半枚举+二分)
Sumsets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11946 Accepted: 3299 Descript ...
- 【折半枚举+二分】POJ 3977 Subset
题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- Codeforces H. Prime Gift(折半枚举二分)
题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...
- POJ 2785 4 Values whose Sum is 0(折半枚举+二分)
4 Values whose Sum is 0 Time Limit: 15000MS Memory Limit: 228000K Total Submissions: 25675 Accep ...
- POJ 3977:Subset(折半枚举+二分)
[题目链接] http://poj.org/problem?id=3977 [题目大意] 在n个数(n<36)中选取一些数,使得其和的绝对值最小. [题解] 因为枚举所有数选或者不选,复杂度太高 ...
随机推荐
- Ubuntu 14.04 下安装redis后运行redis-cli 报出redis Connection refused错误【已解决】
在运行redis-cli运行后爆出错误,看了网上的都没有用例如:改ip,注释bind 127.0.0.1,或者是先运行./redis-server redis.conf,都没有用 只需要: 找到red ...
- 在servlet中获取out.print("")
只需要添加这一句代码 PrintWriter out=resp.getWriter();
- 【原】Python基础-__init__
#py中,有些名称前后都会加上俩个下划线,是有特殊含义的#在Py中,由这些名字组成的集合所包含的方法称为 “魔法方法”.如果在你的对象中#实现了这些方法的其中某一个,那这些方法会被py自动调用,几乎没 ...
- 走进JavaWeb技术世界2:JSP与Servlet的曾经与现在
转载自:码农翻身 转自: 刘欣 码农翻身 1周前 我是Servlet, 由于很多框架把我深深地隐藏了起来,我变得似乎无关紧要了,很多人也选择性的把我给遗忘了. 其实,我还活得好好的呢, 只不过是从前台 ...
- Maven的几种新建项目方式
1. 使用原型创建Maven的java工程 (1) 选择 JDK 的版本,勾选“使用原型创建”,选中 maven-archetype-quickstart,下一步. (2) 填写公司名,填写项目名,修 ...
- nltk data 离线安装
运行程序时发现如下错误: 在命令行下载速度太慢,因此需要离线安装: 按照:http://www.nltk.org/data.html 中manual installation的方法, 将包下载好后解压 ...
- sqlserver 锁表进程及执行的SQL
--1.查进程select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableNamefrom sys.d ...
- js循环数组(总结)
js循环数组(总结) 一.总结 一句话总结: for循环:for(j = 0,len=arr.length; j < len; j++) {} foreach循环:arr.forEach((it ...
- CentOS7 docker开启tcp端口并进行客户端远程连接
#docker版本:18.09.0,最好保证客户端端口和服务端端口相同 [root@Centos7 ~]# dockerd-ce -v Docker version , build 4d60db4 网 ...
- Xgboost 两种使用方式
原生形式使用Xgboost(import xgboost as xgb) from sklearn import datasets from sklearn.model_selection impor ...