题意:

把一堆数分成两堆,使得两堆的差值最小。

思路:

先把一堆数分成两堆,然后用个set存一堆的所有组合,枚举第一堆的状态,二分查找第二堆接近half_value。

瞎说时间复杂度:O(2^17*34);

(代码来着某位神犇)

  1. #include<iostream>
  2. #include<set>
  3. #include<queue>
  4. #include<cstdio>
  5. #include<math.h>
  6. #include<string.h>
  7. #include<algorithm>
  8. using namespace std;
  9. typedef long long LL;
  10. typedef pair<int,int> PII;
  11. using namespace std;
  12. int n;
  13. vector<int>a,b;
  14. set<int>ss;
  15.  
  16. int main()
  17. {
  18. int T;
  19. scanf("%d",&T);
  20. while(T--)
  21. {
  22. int i=0,x,ans=0;
  23. a.clear();b.clear();
  24. scanf("%d",&n);
  25. for(;i<n/2;i++)
  26. {
  27. scanf("%d",&x);ans+=x;
  28. a.push_back(x);
  29. }
  30. for(;i<n;i++)
  31. {
  32. scanf("%d",&x);ans+=x;
  33. b.push_back(x);
  34. }
  35. int half=ans/2,sum,res;
  36. int sz=b.size();
  37. int num=(1<<sz);
  38. ss.clear();
  39. for(i=0;i<num;i++)
  40. {
  41. sum=0;
  42. for(int p=0;p<sz;p++) if(i&(1<<p)) sum+=b[p];
  43. ss.insert(sum);
  44. }
  45. res=-10000000;
  46. sz=a.size();
  47. num=(1<<sz);
  48. set<int>::iterator it;
  49. for(i=0;i<num;i++)
  50. {
  51. sum=0;
  52. for(int p=0;p<sz;p++) if(i&(1<<p)) sum+=a[p];
  53. if(sum>half) continue;
  54. int diff=half-sum;
  55. it=ss.lower_bound(diff);
  56. if((*it)==diff)
  57. {
  58. res=half;
  59. break;
  60. }
  61. if(it==ss.begin()) continue;
  62. it--;
  63. if((sum+(*it))>res)
  64. res=sum+(*it);
  65. }
  66. res=ans-2*res;
  67. printf("%d\n",res);
  68. }
  69. return 0;
  70. }

ZOJ2868【折半】的更多相关文章

  1. 算法与数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找

    今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找 ...

  2. 基本排序(二)插入排序(直接插入、Shell、折半)

    插入排序是常见的内部排序之一.常见的插入排序包括直接插入排序.Shell排序.折半排序.本篇主要介绍这三个排序. 转载请注明出处——http://www.cnblogs.com/zrtqsk/p/38 ...

  3. 折半查找(java)(边学习边更新)

    ---恢复内容开始--- class ArrayTest3 { public static void main(String[] args) { //int [] arr=new int[]{54,4 ...

  4. C语言之实现函数返回一个数组,以及选择排序,还有折半查找。这是同学的一个作业。。。

    作业的具体要求如下: 编写一个完整的程序,实现如下功能.(1)    输入10个无序的整数.(2)    用选择排序法将以上接收的10个无序整数按从大到小的顺序排序.(3)    要求任意输入一个整数 ...

  5. 排序系列 之 折半插入排序算法 —— Java实现

    基本思想: 折半插入算法是对直接插入排序算法的改进,排序原理同直接插入算法: 把n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只有一个元素,无序表中有n-1个元素:排序过程即每次从无序表中 ...

  6. c语言折半查找

    折半查找又称为二分查找,它的前提是线性表中的记录必须是有序的(通常从小到大有序),线性表必须采用顺序存储. 折半查找的基本思想是 : 在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等 ...

  7. 折半算法的C#实现方式-递归和非递归

    这个算法,相信大家都懂,但是不真正的手动写一遍,总觉得不得劲.这不,手动写一遍就是有不一样的效果出现了. 往左折半,还是往右走比较简单,其实这两个算法最关键的是:退出条件 min > max   ...

  8. 算法与数据结构之折半查找(C语言)

    #include <stdio.h> #include<stdlib.h> int binsearch(int x,int v[],int n);//函数声明 int main ...

  9. IOS- 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序

    /*******************************快速排序 start**********************************///随即取 当前取第一个,首先找到第一个的位置 ...

随机推荐

  1. Unix和Linux历史文化

    1.显示工作目录pwd   print working directory     print name of current/working directory 2.显示自己终端名称tty   pr ...

  2. 将socket通信实现多进程

    我们知道,使用TCP协议需要提前建立连接,这样就只能一对一的传输,但是这样感觉十分单一,如果实现一个服务器能同时和多个客户端同信了? 这里就需要用到多线程. 处理的不同之处就在于:每一个接进来的客户都 ...

  3. Java for LeetCode 123 Best Time to Buy and Sell Stock III【HARD】

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  4. Flask中的CBV和上下文初步解读

    一 . flask中的CBV 相对于Django中的CBV,让我们来看看flask中的CBV是如何实现的 ? from flask import Flask, render_template, url ...

  5. <ReversingEngineering>关于windows32位系统下的dll注入技术经验汇

    上个学期把自己闷在图书馆一直在看关于逆向工程技术方面的书,从入门到初级,现在也敢说自己一条腿已经迈进了这片知识的大门里,因为该博客刚开通先将一些经验记录下来,也是留给自己一方面做个参照. <逆向 ...

  6. Sqooop- 使用Sqoop进行数据的导入导出

    Sqoop是Apache旗下的一个开源框架,专门用来做数据的导入和导出. 官网:https://sqoop.apache.org/ Sqoop的安装非常简单,只需要把下载下来的tar包解压设置两个环境 ...

  7. js 阿拉伯数字转转汉字

    js:(单纯的转汉字,没有个.十.千.万,待我日后完善) var number = 323413290907; var N = [ "零", "一", &quo ...

  8. ActorModel 概念翻译

    学习 skynet 时初次接触到 ActorModel 模型,始终觉得有必要从宏观上了解 ActorModel 的概念,所以以维基上这篇文章为参考,把文章中的部分内容翻译成中文,好让自己体会一下 Ac ...

  9. 局域网扫描IP

    今天有朋友去面试,被问到一个“如何扫描局域网IP”的问题(即找出局域网中当前已使用的IP),朋友回答的不好,回来问我,我首先想到的就是使用ping命令将局域网可分配的IP地址逐个遍历一遍,能ping通 ...

  10. Python 实现「食行生鲜」签到领积分

    用过食行生鲜的同学应该知道,每天可以在食行生鲜签到,签到可以领到 20 积分,在购物时可以抵 2 毛钱.钱虽少,但是积少成多,买菜时可以抵扣一两块钱还是不错的. 今天我们就用 Python 来实现自动 ...