首页 > 代码库 > qwb和李主席

qwb和李主席

qwb和李主席

Time Limit: 4 Sec  Memory Limit: 128 MB

Description

qwb和李主席打算平分一堆宝藏,他们想确保分配公平,可惜他们都太懒了,你能帮助他们嘛?

Input

输入包含多组测试数据,处理到文件结束。

每组测试数据的第一行是一个正整数N(0 <= N <=36 )表示物品的总个数.。

接下来输入N个浮点数(最多精确到分),表示每个物品的价值V(0<V<=1e9)。

Output

对于每组测试数据,输出能够使qwb和李主席各自所得到的物品的总价值之差的最小值(精确到分),每组测试数据输出占一行。

Sample Input

3 0.01 0.1 12 1 1

Sample Output

0.890.00
分析:n很小v很大的情况下不能背包;
   考虑折半搜索,枚举其中一半,然后在另一半中二分即可;
   注意浮点数*200倍变偶数取整的技巧;
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <algorithm>#include <climits>#include <cstring>#include <string>#include <set>#include <bitset>#include <map>#include <queue>#include <stack>#include <vector>#include <cassert>#include <ctime>#include<unordered_map>#define rep(i,m,n) for(i=m;i<=n;i++)#define mod 1000000007#define inf 0x3f3f3f3f#define vi vector<int>#define pb push_back#define mp make_pair#define fi first#define se second#define ll long long#define pi acos(-1.0)#define pii pair<int,int>#define sys system("pause")const int maxn=5e4+10;const int N=5e2+10;using namespace std;ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;}int n,m,k,t;ll a[1<<18],b[1<<18],c[18],d[18];void gao(ll d[],ll a[],int num){    for(int i=0;i<(1<<num);i++)    {        d[i]=0;        for(int j=0;j<num;j++)        {            if(i>>j&1)            {                d[i]+=a[j];            }        }    }}int main(){    int i,j;    while(~scanf("%d",&n))    {        int cnta=0,cntb=0;        ll sum=0;        rep(i,1,n)        {            double x;            scanf("%lf",&x);            ll y=round(x*200);  //(ll)(x*200+0.1);            sum+=y;            if(i<=n/2)c[cnta++]=y;            else d[cntb++]=y;        }        gao(a,c,cnta);        gao(b,d,cntb);        cnta=(1<<cnta);        cntb=(1<<cntb);        sort(b,b+cntb);        ll ret=1e18;        rep(i,0,cnta-1)        {            int pos=lower_bound(b,b+cntb,sum/2-a[i])-b;            if(pos<cntb)ret=min(ret,abs(sum-2*(a[i]+b[pos])));            if(pos-1>=0)ret=min(ret,abs(sum-2*(a[i]+b[pos-1])));        }        printf("%.2f\n",ret/200.0);    }    return 0;}

qwb和李主席