折半枚举——poj3977
暴力搜索超时,但是折半后两部分状态支持合并的情况,可用折半枚举算法
poj3977 给一个序列a[],从里面找到k个数,使其和的绝对值最小
经典折半枚举法+二分解决,对于前一半数开一个map,map[sum]里存下凑出当前sum的最小元素个数
枚举后面一半的所有情况,然后lower_bound去找map里最接近-sum的元素,由于要求输出sum最小并且num也尽量小的答案,所以用pair来存答案
#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 ;
}
折半枚举——poj3977的更多相关文章
- Load Balancing 折半枚举大法好啊
Load Balancing 给出每个学生的学分. 将学生按学分分成四组,使得sigma (sumi-n/4)最小. 算法: 折半枚举 #include <iostrea ...
- CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。
1514: Packs Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 61 Solved: 4[Submit][Status][Web Board] ...
- NYOJ 1091 超大01背包(折半枚举)
这道题乍一看是普通的01背包,最最基础的,但是仔细一看数据,发现普通的根本没法做,仔细观察数组发现n比较小,利用这个特点将它划分为前半部分和后半部分这样就好了,当时在网上找题解,找不到,后来在挑战程序 ...
- Codeforces 888E - Maximum Subsequence(折半枚举(meet-in-the-middle))
888E - Maximum Subsequence 思路:折半枚举. 代码: #include<bits/stdc++.h> using namespace std; #define l ...
- Codeforces 912 E.Prime Gift (折半枚举、二分)
题目链接:Prime Gift 题意: 给出了n(1<=n<=16)个互不相同的质数pi(2<=pi<=100),现在要求第k大个约数全在所给质数集的数.(保证这个数不超过1e ...
- poj_3977 折半枚举
题目大意 给定N(N<=35)个数字,每个数字都<= 2^15. 其中一个或多个数字加和可以得到s,求出s的绝对值的最小值,并给出当s取绝对值最小值时,需要加和的数字的个数. 题目分析 需 ...
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- poj 3977 Subset(折半枚举+二进制枚举+二分)
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 5721 Accepted: 1083 Descripti ...
- CodeForces888E Maximum Subsequence(折半枚举+two-pointers)
题意 给定一个包含\(n\)个数的序列\(a\),在其中任选若干个数,使得他们的和对\(m\)取模后最大.(\(n\leq 35\)) 题解 显然,\(2^n\)的暴枚是不现实的...,于是我们想到了 ...
随机推荐
- SQL Ssever 安装.NET3.5 框架
SQL Ssever 安装.NET3.5 框架 我们在安装 SQL Sever 2014 的时候必须要安装 .NET3.5 框架,然后才能继续安装 SQL Server 2014. 您可能在安装 SQ ...
- ubuntu配置px4编译环境
一.主要参考的内容 px4的开发者手册 https://dev.px4.io/zh/setup/dev_env_linux.html 其中有的shell指令 权限设置 警告:永远不要使用sudo来修复 ...
- sql存储过程循环实现事务
//往一张表中添加数据,获取添加数据生成的ID,再往另一张表中添加多条数据 ALTER PROCEDURE [dbo].[AttendanceCardAndDetail_Add] @SchoolID ...
- <自动化测试>之<SeleniumIDE使用详解 >
最近在做些简单的自动化理解培训,以繁化简,就写了一节selenium ide的使用教程,在这里分享给刚入门的朋友 自动化插件工具介绍: 这是一款基于Firefox的自动化录制插件,UI界面化操作,无需 ...
- Spring MVC rest接收json中文格式数据显示乱码
1.解决方法其中之一 在web.xml下添加配置: <!-- 编码配置 --> <filter> <filter-name>CharacterEncodingFil ...
- Linux 下虚拟机——Virtual Box
下面介绍几款可以在Linux下运行的虚拟机 VMware,VirtualBox, QEMU, Xen.(其中我只用过VirtualBox 和Xen, 我是新手,其他两个没时间折腾,所以下面的资料都几乎 ...
- zju1610Count the Colors
ZOJ Problem Set - 1610 Count the Colors Time Limit: 2 Seconds Memory Limit: 65536 KB Painting s ...
- 避开PCB假八层结构的温柔陷阱---浅谈六层板的叠层
https://blog.csdn.net/qijitao/article/details/51505611 作者:王辉东 一博科技高速先生团队队员 在<PCB的筋骨皮>一文中,我们提 ...
- Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' and Module not found: Error: Can't resolve '@babel/runtime/helpers/defineProperty'
These two mistakes are really just one mistake, This is because the following file @babel/runtime ca ...
- shell-#!
当shell执行一个程序时,会要求UNIX内核启动一个新的进程,以便在该进程里执行所指定的程序. 当系统只有一个shell时,退回到/bin/sh 的机制非常方便,但现行的UNIX系统都会拥有好几个s ...