zoukankan      html  css  js  c++  java
  • [bzoj2679] [Usaco2012 Open]Balanced Cow Subsets

    题目描述

    Farmer John's owns N cows (2 <= N <= 20), where cow i produces M(i) units of milk each day (1 <= M(i) <= 100,000,000). FJ wants to streamline the process of milking his cows every day, so he installs a brand new milking machine in his barn. Unfortunately, the machine turns out to be far too sensitive: it only works properly if the cows on the left side of the barn have the exact same total milk output as the cows on the right side of the barn!

    Let us call a subset of cows "balanced" if it can be partitioned into two groups having equal milk output. Since only a balanced subset of cows can make the milking machine work, FJ wonders how many subsets of his N cows are balanced. Please help him compute this quantity.

    给n个数,从中任意选出一些数,使这些数能分成和相等的两组。

    求有多少种选数的方案。

    输入输出格式

    输入格式:

    * Line 1: The integer N.

    * Lines 2..1+N: Line i+1 contains M(i).

    输出格式:

    * Line 1: The number of balanced subsets of cows.

    输入输出样例

    输入样例#1:

    4 
    1 
    2 
    3 
    4 
    

    输出样例#1:

    3 
    

    说明

    There are 4 cows, with milk outputs 1, 2, 3, and 4.

    There are three balanced subsets: the subset {1,2,3}, which can be partitioned into {1,2} and {3}, the subset {1,3,4}, which can be partitioned into {1,3} and {4}, and the subset {1,2,3,4} which can be partitioned into {1,4} and {2,3}.

    此为luogu题面,bzoj题面(权限题)

    题解

    折半搜索(meet in the middle)经典题。

    搜索前面一半和后面一半,记下每种状态(选了哪些数)和两个集合的差值,然后分别对于差值排序,做一遍two pointer,注意每种状态只能算一次,要开个数组记录下哪些状态已经算过了。

    #include<bits/stdc++.h>
    using namespace std;
     
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
     
    void print(int x) {
        if(x<0) x=-x,putchar('-');
        if(!x) return ;print(x/10),putchar(x%10+'0');
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
     
    #define maxn 22
     
    int v[maxn],n,m,vis[1<<maxn],tot,sum[1<<13],tot2;
    struct data {
        int sta,val;
        bool operator < (const data &rhs) const {return val<rhs.val;}
    }a[60000],b[60000];
     
    signed main() {
        read(n);for(int i=1;i<=n;i++) read(v[i]);
        m=(n>>1)+(n&1);if(n<=1) return puts("0"),0;
        for(int s=0;s<(1<<m);s++)
            for(int i=0;i<m;i++) if((s>>i)&1) sum[s]+=v[i+1];
        for(int s=0;s<(1<<m);s++) 
            for(int i=s;i;i=(i-1)&s)
                a[++tot].val=sum[i]-sum[s^i],a[tot].sta=s;
        a[++tot]=(data){0,0};
        sort(a+1,a+tot+1);
        memset(sum,0,sizeof sum);
        for(int s=0;s<(1<<(n-m));s++) 
            for(int i=0;i<(n-m);i++) if((s>>i)&1) sum[s]+=v[i+m+1];
        for(int s=0;s<(1<<(n-m));s++)
            for(int i=s;i;i=(i-1)&s)
                b[++tot2].val=sum[i]-sum[s^i],b[tot2].sta=s;//,printf("%d %d %d
    ",s,b[tot2].val,i);
        b[++tot2]=(data){0,0};
        sort(b+1,b+tot2+1);
        //for(int i=1;i<=tot;i++) printf("%d %d
    ",a[i].sta,a[i].val);puts("");
        //for(int i=1;i<=tot2;i++) printf("%d %d
    ",b[i].sta,b[i].val);
        int p1=1,p2=1,ans=-1;
        for(;p1<=tot;p1++) {
            while(a[p1].val>b[p2].val&&p2<=tot2) p2++;
            for(int i=p2;b[i].val==a[p1].val&&i<=tot2;i++) {
                int res=a[p1].sta|(b[i].sta<<m);
                if(!vis[res]) vis[res]=1,ans++;//,printf("%d %d %d %d
    ",a[p1].sta,b[i].sta,a[p1].val,b[i].val);
            }
        }write(ans);
        return 0;
    }
    
  • 相关阅读:
    .NETCore 之 中间件 02
    .NETCore 之 中间件 01
    .NetCore 之AOP扩展ExceptionFilter
    Unity ICO
    CentOS7离线安装Mysql8.0
    CentOS7离线安装devtoolset-9并编译redis6.0.5
    Centos7离线安装gcc4.8
    C#进行图片压缩(对jpg压缩效果最好)
    实现ASP.Net Core3.1运行在DockeDesktop下并用Nginx实现负载均衡
    WPF实现TextBlock呼吸灯效果
  • 原文地址:https://www.cnblogs.com/hbyer/p/10026902.html
Copyright © 2011-2022 走看看