记录编号 128334 评测结果 AAAAAAAAAAAAAAAAAAAAA
题目名称 [USACO Open12] 平衡奶牛子集 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.233 s
提交时间 2014-10-17 09:20:08 内存使用 1.77 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int SIZEN=25;
typedef pair<int,int> PR;//first是值,second是二进制码
int N,n;
int a[SIZEN]={0};
int tot=0;
PR state[60000];
bool able[1<<20]={0};
void unique(void){
	sort(state,state+tot);
	int k=0;
	for(int i=0;i<tot;i++)
		if(i==0||state[i]!=state[i-1]) state[k++]=state[i];
	tot=k;
}
void check(PR s){
	int x=-s.first;
	int l=0,r=tot;
	while(l<r){//我们找到第一个>=x的位置
		int mid=(l+r)/2;
		if(state[mid].first>=x) r=mid;
		else l=mid+1;
	}
	while(l<tot&&state[l].first==x){
		able[state[l].second|s.second]=true;
		l++;
	}
}
void DFS2(int p,PR s){
	if(p==N){
		check(s);
		return;
	}
	for(int i=-1;i<=1;i++){
		PR t=s;
		t.first+=i*a[p];
		if(i) t.second|=(1<<p);
		DFS2(p+1,t);
	}
}
void DFS1(int p,PR s){
	if(p==n){
		state[tot++]=s;
		return;
	}
	for(int i=-1;i<=1;i++){
		PR t=s;
		t.first+=i*a[p];
		if(i) t.second|=(1<<p);
		DFS1(p+1,t);
	}
}
void answer(void){
	int ans=0;
	for(int i=(1<<N)-1;i>0;i--) ans+=able[i];
	printf("%d\n",ans);
}
void read(void){
	scanf("%d",&N);
	for(int i=0;i<N;i++) scanf("%d",&a[i]);
	n=N/2;
}
int main(){
	freopen("subsets.in","r",stdin);
	freopen("subsets.out","w",stdout);
	read();
	DFS1(0,make_pair(0,0));
	unique();
	DFS2(n,make_pair(0,0));
	answer();
	return 0;
}