zoukankan      html  css  js  c++  java
  • TZOJ 1503 Incredible Cows(折半搜索+二分)

    描述

    Farmer John is well known for his great cows. Recently, the cows have decided to participate in the Incredible Cows Puzzle Contest (ICPC).

    Farmer John wants to divide the cows into two teams, and he wants to minimize the difference of Puzzle Solving Power of two teams.

    Puzzle Solving Power of a team is sum of Puzzle Solving Power of cows forming that team.

    Help F.J. to find the minimum difference!

    输入

    The first line of input consists of a single integer T, the number of test-cases. Each test-case consists of a line containing n (2 <= n <= 34), number of cows. n lines follow. i-th line contains the Puzzle Solving Power of i-th cow. Puzzle Solving Power of a cow is a non-negative number less than 10,000,000. There is a blank line between two consecutive test-cases.

    输出

    For each test-case, output a line containing the minimum difference which can be achieved.

    样例输入

    2
    3
    12
    6
    6

    10
    123
    455
    1000
    403
    234
    554
    129
    454
    84
    11

    样例输出

    0
    5

    题意

    把n数分成两堆,使得两堆和的差最小。

    题解

    n高达34,直接爆搜肯定不行。但是17可以直接爆搜(2^17)。

    于是乎,相当于把数组对半拆开,记和为suml和sumr,然后爆搜出两堆的所有情况。

    然后就是配对问题了,假设第一堆取出了X,第二堆取出了Y。

    答案是最小化函数|(X+Y)-((suml-X)+(sumr-Y))|,化简得到|2X+2Y-suml-sumr|。

    我们枚举一个未知数X,那么变成绝对值函数,易得Y>=(suml+sumr)/2-X,于是lower_bound找到最小的Y。

    这是最小值在右边的情况,还有在左的情况就是二分得到的Y前一个数。

    时间复杂度O(2^17*log(2^17))。

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 ll a[35];
     6 set<ll>se[2];
     7 void dfs(int s,int t,bool f,ll sum)
     8 {
     9     if(s>t)
    10     {
    11         se[f].insert(sum);
    12         return;
    13     }
    14     dfs(s+1,t,f,sum+a[s]);
    15     dfs(s+1,t,f,sum);
    16 }
    17 int main()
    18 {
    19     int n,t;
    20     cin>>t;
    21     while(t--)
    22     {
    23         se[0].clear(),se[1].clear();
    24         cin>>n;ll suml=0,sumr=0;
    25         for(int i=1;i<=n/2;i++)cin>>a[i],suml+=a[i];
    26         for(int i=n/2+1;i<=n;i++)cin>>a[i],sumr+=a[i];
    27         dfs(1,n/2,0,0);dfs(n/2+1,n,1,0);
    28         ll min_abs=1e18;
    29         set<ll>::iterator it,itt;
    30         for(auto X:se[0])
    31         {
    32             it=se[1].lower_bound((suml+sumr)/2-X);
    33             itt=it;
    34             if(it!=se[1].begin())--itt;
    35             if(it==se[1].end())--itt,--it;
    36             min_abs=min(min_abs,min(abs(suml+sumr-2*X-2*(*it)),abs(suml+sumr-2*X-2*(*it))));
    37         }
    38         cout<<min_abs<<'
    ';
    39     }
    40     return 0;
    41 }
  • 相关阅读:
    2017.9.29 ubuntu安装mysql服务
    如何在树莓派上安装mjpeg-streamer(针对摄像头为UVC的)
    2016.9.22感想及收获
    GL-iNET路由器如何安装DDNS服务
    2016.7.5 记项目过程中犯的一个从未察觉的低级错误
    C++课程笔记 Lesson 01
    关于Jlink在linux系统下连接错误的解决方法
    如何通过命令提示符进入MySQL服务器
    java面试题
    hive面试题
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/11960263.html
Copyright © 2011-2022 走看看