Subset---poj3977(折半枚举+二分查找)
题目链接:http://poj.org/problem?id=3977
给你n个数,找到一个子集,使得这个子集的和的绝对值是最小的,如果有多种情况,输出子集个数最少的;
n<=35,|a[i]|<=10e15
子集个数共有2^n个,所以不能全部枚举,但是可以分为两部分枚举;
枚举一半的所有情况,然后后一半二分即可;
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
#define N 45
#define PI 4*atan(1.0)
#define mod 1000000007
#define met(a, b) memset(a, b, sizeof(a))
#define INF 10000000000000000
typedef long long LL; int n;
LL a[N]; LL Abs(LL x)
{
return x<?-x:x;
} int main()
{
while(scanf("%d", &n), n)
{
for(int i=; i<n; i++)
scanf("%I64d", &a[i]); map<LL, int> M;
map<LL, int>::iterator it;
pair<LL, int> ans(Abs(a[]), ); for(int i=; i<<<(n/); i++)
{
LL sum = ;int cnt = ;
for(int j=; j<(n/); j++)
{
if((i>>j)&)
{
sum += a[j];
cnt ++;
}
}
ans = min(ans, make_pair(Abs(sum), cnt));///全部是前半部分的;
if(M[sum])///更新cnt为小的;
M[sum] = min(M[sum], cnt);
else
M[sum] = cnt;
} for(int i=; i<<<(n-n/); i++)
{
LL sum = ;int cnt = ;
for(int j=; j<(n-n/); j++)
{
if((i>>j)&)
{
sum += a[j+n/];
cnt ++;
}
}
ans = min(ans, make_pair(Abs(sum), cnt));///全部是后半部分的; it = M.lower_bound(-sum);///找到第一个大于-sum的位置,然后取两种情况的最小值; if(it != M.end())
ans = min(ans, make_pair(Abs(sum+it->first), cnt+it->second));
if(it != M.begin())
{
it--;
ans = min(ans, make_pair(Abs(sum+it->first), cnt+it->second));
}
}
printf("%I64d %d\n", ans.first, ans.second);
}
return ;
}
Subset---poj3977(折半枚举+二分查找)的更多相关文章
- CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。
1514: Packs Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 61 Solved: 4[Submit][Status][Web Board] ...
- poj3977(折半枚举+二分查找)
题目链接:https://vjudge.net/problem/POJ-3977 题意:给一个大小<=35的集合,找一个非空子集合,使得子集合元素和的绝对值最小,如果有多个这样的集合,找元素个数 ...
- 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(折半枚举+二分)
[题目链接] http://poj.org/problem?id=3977 [题目大意] 在n个数(n<36)中选取一些数,使得其和的绝对值最小. [题解] 因为枚举所有数选或者不选,复杂度太高 ...
- poj 3977 Subset(折半枚举+二进制枚举+二分)
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 5721 Accepted: 1083 Descripti ...
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- 【折半枚举+二分】POJ 3977 Subset
题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...
- POJ 2549 Sumsets(折半枚举+二分)
Sumsets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11946 Accepted: 3299 Descript ...
- SPOJ11469 Subset(折半枚举)
题意 给定一个集合,有多少个非空子集,能划分成和相等的两份.\(n\leq 20\) 题解 看到这个题,首先能想到的是\(3^n\)的暴力枚举,枚举当前元素是放入左边还是放入右边或者根本不放,但是显然 ...
随机推荐
- 百度搜索词&淘宝搜索词 接口实现
百度和淘宝并没有正式的提供一个公开API给我们用,但是经过分析他们的源代码,还是找到了解决方法. 1 2 3 4 5 6 7 8 9 /*baidu&taobao callback*/ fun ...
- 【BZOJ】1452: [JSOI2009]Count
http://www.lydsy.com/JudgeOnline/problem.php?id=1452 题意:n×m的矩阵上每个点有个颜色,现在有q个操作:1 x y c 将点(x,y)的颜色改为c ...
- 【BZOJ】1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1862 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- eclipse远程调试Tomcat方法
1.Linux中配置tomcat在catalina.sh中添加如下CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address= ...
- QMessageBox 使用方法
在Qt中经常需要弹出窗口,QMessageBox可以实现此功能,一共有三种窗口,information, question, 和 warning,critical, about分别对应感叹号,问号和叉 ...
- Odoo Auto Backup Database And Set Linux task schedualer
First ,Write Database Backup Script: pg_dump -Fc yourdatabasename > /home/yourfilepath/yourdataba ...
- 关于如何用php 获取当前脚本的url
关于用php 获取当前脚本的url很多朋友会说很简单,但是要获取很详细的就要经过多次判断哦. $PHP_TIME = time();$PHP_SELF = isset($_SERVER['PHP_SE ...
- 打包bat等文件成exe,双击运行不显示dos窗口,exe不报毒
准备材料如下bat和vbs直接新建文本,然后改后缀就可以建出来了(后面发现exe运行vbs来启动bat不报毒)下面内容就是要把这些文件打包成exe,双击exe后打开图片test.jpg,不显示dos窗 ...
- ci实现RBAC,详细解释原理和核心代码显示
代码实现不复杂,主要是思路的理解 RBAC是基于权限控制 1.权限结点管理 2.角色管理 3.管理员权限分配 结点管理就是把所有的分组 控制器 方法全部写入一个结点管理表 请注意在写一个动作比如,展示 ...
- PHP 错误与异常 笔记与总结(13 )自定义异常类
针对不同的异常,进行不同的处理,可以通过自定义异常类记录特定的异常信息来处理不同类型的异常.自定义异常类通过继承基类(Exception),对基类进行扩展. 自定义异常类 <?php heade ...