Subset POJ - 3977(折半枚举+二分+二进制枚举)

题意:

给你一个集合N(N<=35),问集合的子集,除了空集,使得自己中所有元素和的绝对值最小,若存在多个值,那么选择子集中元素最少的那个。

题目:

Given a list of N integers with absolute values no larger than 101510^{15}1015, find a non empty subset of these numbers which minimizes the absolute value of the sum of its elements. In case there are multiple subsets, choose the one with fewer elements.

Input

The input contains multiple data sets, the first line of each data set contains N <= 35, the number of elements, the next line contains N numbers no larger than 1015 in absolute value and separated by a single space. The input is terminated with N = 0

Output

For each data set in the input print two integers, the minimum absolute sum and the number of elements in the optimal subset.

Sample Input

1
10
3
20 100 -100
0

Sample Output

10 1
0 2

分析:

1.n 最大到 35,每个数有选、不选两种可能,最多有 2352^{35}235 个子集,因此暴力枚举的话,一定会Time Limit Exceed,采用折半枚举的思想,分成两个集合,这样每边最多 18 个元素,分别进行枚举,复杂度降到 2182^{18}218
2.利用二进制将和以及元素个数存在两个数组中,先预判是否满足题意,再将其中一个元素和取相反数后排序,因为总元素和越接近零越好,再二分查找即可,用lower_bound时考虑查找到的下标和他前一个下标,比较元素和以及元素个数,不断更新即可。
3.由于是求大数的绝对值,此时需要开函数,(不知道为什么,我调用labs函数,结果是错误的,所以自己写了一个)
4.然后枚举其中一个子集,排序后暂存后,再枚举另一个子集,通过二分查找第一个集合中与该值的相反数最接近的元素,要注意的是如果有多个元素与相反值最接近,取数的个数最小的那一个。
5.与寻找合适的子集并与第一个集合的子集相加,从而找到绝对值最小的子集.
下面附上AC代码,里面注解有部分解答。

AC代码:

#include<stdio.h>
#include<map>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int M=50;
int n,cnt=0;
map<ll,ll> vis;
ll Labs(ll x){if(x>0) return x;return -x;
}
ll a[M],dp[1<<20],ans;//vis当前所选的最少个数,dp数组存储前一半的值,ans是最终结果
ll solve(ll num)
{if(num<=dp[1])return dp[1];else if(num>=dp[cnt])return dp[cnt];int mid=upper_bound(dp+1,dp+cnt+1,num)-dp;if(Labs(dp[mid]-num)==Labs(dp[mid-1]-num)){if(vis[dp[mid-1]]<vis[dp[mid]])return dp[mid-1];return dp[mid];}else if(Labs(dp[mid]-num)>Labs(dp[mid-1]-num))return dp[mid-1];return dp[mid];
}//查找与x最接近的元素,要注意的是如果有多个元素与x最接近,取数的个数最小的那一个
int main()
{while(~scanf("%d",&n)&&n){cnt=0,ans=inf;vis.clear();memset(a,0,sizeof(a));memset(dp,0,sizeof(dp));for(int i=1; i<=n; i++)scanf("%lld",&a[i]);if(n==1){printf("%lld 1\n",Labs(a[1]));continue;}int x=n/2,y=n-x;int mi=(1<<x)-1;/*mi为所选元素的所有可能性,除去空集*/ll id=inf;for(int i=1; i<=mi; i++){ll now=0,tot=0;for(int j=1; j<=x; j++){if(i&(1<<(j-1)))/**枚举i为多少种方式,j为多少个数,用j来控制位数,i控制方式*/now+=a[j],tot++;}if(vis[now])vis[now]=min(vis[now],tot);//如果当前值已经出现过,元素个数取较小的elsevis[now]=tot,dp[++cnt]=now;//没有出现过,建立映射关系if(Labs(now)<ans){ans=Labs(now);id=tot;}//如果答案更优,更新答案else if(Labs(now)==ans)id=min(id,tot);//如果答案相同,元素个数取较小的}sort(dp+1,dp+cnt+1);for(int i=1; i<=(1<<y)-1; i++){ll now=0,tot=0;for(int j=1; j<=y; j++)if(i&(1<<(j-1)))now+=a[j+n/2],tot++;if(Labs(now)<ans){ans=Labs(now);id=tot;}else if(Labs(now)==ans)id=min(id,tot);ll num=solve(-now);//二分找到与相反数最接近的数if(ans>Labs(num+now)){ans=Labs(num+now);id=tot+vis[num];}else if(ans==Labs(num+now))id=min(id,tot+vis[num]);}printf("%lld %d\n",ans,id);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309503.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET内存管理五大基础知识

1.小对象怎么处理的&#xff1f;小型.NET对象被分配到小型对象堆&#xff08;SOH&#xff09;上。其中有3种&#xff1a;第0代&#xff0c;第1代和第2代。对象根据其寿命向上移动。将新对象放在Gen 0上。当Gen 0充满时&#xff0c;.NET垃圾收集器&#xff08;GC&#xff09;运行…

L1-046 整除光棍 (20分)(模拟除法竖式求商的位运算)

题目&#xff1a; 这里所谓的“光棍”&#xff0c;并不是指单身汪啦~ 说的是全部由1组成的数字&#xff0c;比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如&#xff0c;111111就可以被13整除。 现在&#xff0c;你的程序要读入一个整数x&#…

Sql Server之旅——第十站 简单说说sqlserver的执行计划

我们知道sql在底层的执行给我们上层人员开了一个窗口&#xff0c;那就是执行计划&#xff0c;有了执行计划之后&#xff0c;我们就清楚了那些烂sql是怎么执行的&#xff0c;这样 就可以方便的找到sql的缺陷和优化点。一&#xff1a;执行计划生成过程说到执行计划&#xff0c;首…

【半译】扩展shutdown超时设置以保证IHostedService正常关闭

我最近发现一个问题&#xff0c;当应用程序关闭时&#xff0c;我们的应用程序没有正确执行在IHostedService中的StopAsync方法。经过反复验证发现&#xff0c;这是由于某些服务对关闭信号做出响应所需的时间太长导致的。在这篇文章中&#xff0c;我将展示出现这个问题的一个示例…

java基础知识——基础语法

java的基本语法格式 [修饰符] class 类名{程序代码 }方法的定义 一般情况下&#xff0c;定义一个方法包含以下语法&#xff1a; 修饰符 返回值类型 方法名(参数类型 参数名){...方法体...return 返回值; }JAVA标识符规范&#xff1a; 1.标识符可以由任意顺序的大小写字母、…

[JavaWeb-MySQL]多表关系介绍

多表之间的关系 1. 分类&#xff1a;1. 一对一(了解)&#xff1a;* 如&#xff1a;人和身份证* 分析&#xff1a;一个人只有一个身份证&#xff0c;一个身份证只能对应一个人2. 一对多(多对一)&#xff1a;* 如&#xff1a;部门和员工* 分析&#xff1a;一个部门有多个员工&am…

Asp.Net Core多榜逆袭,这是.NET最好的时代!

摒弃侥幸之念&#xff0c;必取百炼成钢。厚积分秒之功&#xff0c;始得一鸣惊人&#xff01;经过多年的沉沦&#xff0c;.NET终于迎来逆袭&#xff01;近期连出多个排行榜&#xff0c;Asp.Net Core直接霸榜&#xff0c;这意味着属于.Neter的好时代的即将到来&#xff01;.Net C…

[JavaWeb-MySQL]数据库的备份和还原

数据库的备份和还原 1. 命令行&#xff1a;* 语法&#xff1a;* 备份&#xff1a; mysqldump -u用户名 -p密码 数据库名称 > 保存的路径* 还原&#xff1a;1. 登录数据库2. 创建数据库3. 使用数据库4. 执行文件。source 文件路径 2. 图形化工具&#xff1a;备份完成!!! 现…

SiteServer CMS 新版本 V6.15(2020年6月1日发布)

欢迎来到 SiteServer CMS V6.15版本&#xff0c;新版本重点增加了 REST API 的接口调用&#xff0c;同时修复了多项BUG:REST API 接口增强&#xff1a;通过REST API&#xff0c;第三方系统可以很好地集成 SiteServer CMS&#xff0c;以下是最新的API接口&#xff0c;涵盖了CMS操…

JAVA中小细节(易忽视和易错点)

在为一个long类型的变量赋值时&#xff0c;所赋值的后面要加上一个字母L&#xff08;l&#xff09;&#xff0c;说明赋值为long类型&#xff0c;但如果赋值未超出int取值范围&#xff0c;可以忽略。在为一个float类型的变量赋值时&#xff0c;所赋值的后面要加上一个字F&#x…

[JavaWeb-MySQL]多表查询(内连接,外连接,子查询)

多表查询的分类&#xff1a; 1. 内连接查询&#xff1a;1. 隐式内连接&#xff1a;使用where条件消除无用数据* 例子&#xff1a;-- 查询所有员工信息和对应的部门信息SELECT * FROM emp,dept WHERE emp.dept_id dept.id;-- 查询员工表的名称&#xff0c;性别。部门表的名称SE…

全局变量初始化顺序探究

缘起 我在上一篇文章——《调试实战 —— dll 加载失败之全局变量初始化篇》中&#xff0c;跟大家分享了一个由于全局变量初始化顺序导致的 dll 加载失败的例子。感兴趣的小伙伴儿可以点击阅读。虽然我们知道了是由于全局变量初始化顺序导致的问题&#xff0c;也给出了解决方案…

java基础知识——面向对象基本概念

文章目录Java基本概念源文件声明规则Java包Import语句继承类型继承的特性继承关键字super 与 this 关键字构造器方法的重写规则重载(Overload)重写与重载之间的区别java 接口接口与类相似点&#xff1a;接口与类的区别&#xff1a;接口特性抽象类和接口的区别接口的声明接口的实…

[JavaWeb-MySQL]多表查询练习

-- 部门表 CREATE TABLE dept (id INT PRIMARY KEY PRIMARY KEY, -- 部门iddname VARCHAR(50), -- 部门名称loc VARCHAR(50) -- 部门所在地 );-- 添加4个部门 INSERT INTO dept(id,dname,loc) VALUES (10,教研部,北京), (20,学工部,上海), (30,销售部,广州), (40,财务部,深圳)…

基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(三)

上一篇完成了全网各大平台的热点新闻数据的抓取&#xff0c;本篇继续围绕抓取完成后的操作做一个提醒。当每次抓取完数据后&#xff0c;自动发送邮件进行提醒。在开始正题之前还是先玩一玩之前的说到却没有用到的一个库PuppeteerSharp。PuppeteerSharp&#xff1a;Headless Chr…

创建型模式——工厂模式

一、 实验目的与要求 1.练习使用工厂模式。设计相关的模拟场景并进行实施&#xff0c;验证模式特性&#xff0c;掌握其优缺点。 2.实验结束后&#xff0c;对相关内容进行总结。 二、实验内容 1.模式应用场景说明 作为一个青年人&#xff0c;最好的伙伴就是手机。而手机最重…

[JavaWeb-MySQL]事务的基本介绍

事务的基本介绍 1. 概念&#xff1a;* 如果一个包含多个步骤的业务操作&#xff0c;被事务管理&#xff0c;那么这些操作要么同时成功&#xff0c;要么同时失败。2. 操作&#xff1a;1. 开启事务&#xff1a; start transaction;2. 回滚&#xff1a;rollback;3. 提交&#xff…