Subset
Time Limit: 30000MS   Memory Limit: 65536K
Total Submissions: 1373   Accepted: 228

Description

Given a list of N integers with absolute values no larger than 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

Source

 
 
把集合分成两个 N / 2的集合,然后生成一种一个集合2 ^ (n - 1)种状态的和,对于另一个集合的所有状态的和 在前一个集合中二分找到一个最接近的
并找到集合元素最小的即是所求答案
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility> using namespace std; typedef long long ll;
typedef pair<ll,int> pii; const ll INF = (1e17) + ;
const int MAX = ; int N;
ll w[MAX];
pii ps[( << ) + ];
int cal[ << ],dx[] = {-,-,,}; ll Abs(ll x) {
return x > ? x : -x;
} void init() {
for(int s = ; s < ( << ); ++s) {
int sum = ;
for(int i = ; i < ; ++i) {
if(s >> i & ) ++sum;
}
cal[s] = sum;
}
}
void solve() {
int n = N / ;
ll sw = ;
for(int s = ; s < ( << n); ++s) {
sw = ;
for(int j = ; j < n; ++j) {
if(s >> j & ) sw += w[j];
}
ps[s] = make_pair(sw,cal[s]);
}
sort(ps,ps + ( << n)); int n1 = N - n;
ll ansv = INF;
int anss = N;
for(int s = ; s < ( << n1); ++s) {
sw = ;
for(int j = n; j < N; ++j) {
if(s >> (j - n) & ) sw += w[j];
}
int pos = lower_bound(ps,ps + ( << n),make_pair(-sw,-)) - ps;
ll v = INF,t = INF;
for(int i = ; i < ; ++i) {
int id = pos + dx[i];
if(id >= && id < ( << n)
&& (ps[id].second || s)) {
if(Abs(ps[id].first + sw) < t) {
t = Abs(ps[id].first + sw);
v = ps[id].first;
}
}
}
pos = lower_bound(ps,ps + ( << n),make_pair(v,-)) - ps;
if(s == && ps[pos].second == ) ++pos;
if(ansv > Abs(v + sw) || ansv == Abs(v + sw) && anss > cal[s] + ps[pos].second) {
ansv = Abs(v + sw);
anss = cal[s] + ps[pos].second;
}
} printf("%I64d %d\n",ansv,anss);
} int main()
{
freopen("sw.in","r",stdin);
init();
while(~scanf("%d",&N) && N) {
for(int i = ; i < N; ++i) scanf("%I64d",&w[i]);
solve();
} return ;
}

POJ 3977的更多相关文章

  1. POJ 3977 - subset - 折半枚举

    2017-08-01 21:45:19 writer:pprp 题目: • POJ 3977• 给定n个数,求一个子集(非空)• 使得子集内元素和的绝对值最小• n ≤ 35 AC代码如下:(难点:枚 ...

  2. POJ 3977 折半枚举

    链接: http://poj.org/problem?id=3977 题意: 给你n个数,n最大35,让你从中选几个数,不能选0个,使它们和的绝对值最小,如果有一样的,取个数最小的 思路: 子集个数共 ...

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

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

  4. POJ 3977 Subset

    Subset Time Limit: 30000MS   Memory Limit: 65536K Total Submissions: 3161   Accepted: 564 Descriptio ...

  5. poj 3977 Subset(折半枚举+二进制枚举+二分)

    Subset Time Limit: 30000MS   Memory Limit: 65536K Total Submissions: 5721   Accepted: 1083 Descripti ...

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

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

  7. Divide and conquer:Subset(POJ 3977)

    子序列 题目大意:给定一串数字序列,要你从中挑一定个数的数字使这些数字和绝对值最小,求出最小组合数 题目的数字最多35个,一看就是要数字枚举了,但是如果直接枚举,复杂度就是O(2^35)了,显然行不通 ...

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

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

  9. poj 3977 子集

    题目 题意:在一个集合中找到一个非空子集使得这个子集元素和的绝对值尽量小,和绝对值相同时保证元素个数尽量小 分析:1.二分枚举的思想,先分成两个集合: 2.枚举其中一个集合中所有的子集并且存到数组中, ...

随机推荐

  1. ARP协议格式、ARP运行机制入门学习

    相关学习资料 http://baike.baidu.com/view/149421.htm?fromtitle=ARP%E5%8D%8F%E8%AE%AE&fromid=1742212& ...

  2. groovy-真值

    Boolean expressions Groovy支持标准的条件运算符的布尔表达式: 1 def a = true 2 def b = true 3 def c = false 4 assert a ...

  3. 桂电在linux环境下使用出校器

    一.官方出校器(无界面) 由于学校官方最新的linux版出校器无效,我们只能使用老版本的出校器了. 但因为老版本的出校器是32位的,而现在主流使用的是64位系统,因此我们得安装32位库. 在ubunt ...

  4. java的static块执行时机

    一.误区:简单认为JAVA静态代码块在类被加载时就会自动执行.证错如下: class MyClass1 { static {//静态块 System.out.println("static  ...

  5. js中网页图片自动更换的效果

    <script> var arr=new Array(); arr[]="url(images/city.jpg)"; arr[]="url(images/d ...

  6. Python socket编程之三:模拟数据库循环发布数据

    1. f1.py # -*- coding: utf-8 -*- import socket import struct import sqlalchemy import pandas ####### ...

  7. Unity Shader Billboard

    记录来源于ShaderLab开发实战详解 Shader "Tut/Project/Billboard_1" { Properties { _MainTex ("Base ...

  8. goquery

    使用goquery 会用jquery的,goquery基本可以1分钟上手,下面是goquery文档 http://godoc.org/github.com/PuerkitoBio/goquery 1. ...

  9. Ueditor的两种定制方式

    引言 UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... 官网:http://ueditor ...

  10. [转载]如何在Ubuntu上安装LAMP服务器系统

    [2013年7月25日 51CTO外电头条]为何应该在Ubuntu上安装LAMP服务器?从事Web开发工作时,我更偏爱在不受干扰的情况下,在我那台计算机上的开发环境下进行开发.我宁愿所犯的错误大部分是 ...