【折半搜索】BZOJ2679(Usaco2012 Open)[Balanced Cow Subsets]题解
2017-10-27 19:37
696 查看
题目概述
给出 n 个数( n≤20 ),现在从中选出若干个数(不可不选),若这若干个数能分成两个加和相等的集合,则是一种合法方案。求合法方案数。解题报告
如果直接枚举,状态有 320 ,显然是不行的。但如果已知一些数的状态,再枚举其他数的状态,是可以快速统计的。所以考虑折半搜索。但由于是选出若干个数,问这些数是否有合法方案,所以需要记录每种方案的状态,否则会算重复。
我秉承不用map的原则(狗屁嘞,明明就是偷懒用map发现超时)打了哈希表。
好像有dalao用two-pointer做啊……但是貌似被我cao了。
复杂度比较玄学,好像有复杂度稳定的正解,可以Orz Manchery。
示例程序
#include<cstdio> #include<vector> using namespace std; typedef long long LL; const int maxn=20,maxe=59049,MOD=999917,MAXINT=((1<<30)-1)*2+1; int n,a[maxn+5],ans; int E,lnk[MOD],nxt[maxe+5];LL son[maxe+5]; vector<int> w[maxe+5];bool vis[1<<maxn]; inline void Insert(LL x,int s) { for (int j=lnk[(x+=MAXINT)%MOD];j;j=nxt[j]) if (son[j]==x) {w[j].push_back(s);return;} son[++E]=x;w[E].push_back(s);nxt[E]=lnk[x%MOD];lnk[x%MOD]=E; } inline int Find(LL x) { for (int j=lnk[(x+=MAXINT)%MOD];j;j=nxt[j]) if (son[j]==x) return j; return 0; } void Dfs(int L,int R,int sum=0,int s=0) { if (L>R) return Insert(sum,s); Dfs(L+1,R,sum,s);Dfs(L+1,R,sum-a[L],s+(1<<L-1));Dfs(L+1,R,sum+a[L],s+(1<<L-1)); } void Count(int L,int R,int sum=0,int s=0) { if (L>R) { for (int j=Find(-sum),i=0;i<w[j].size();i++) if (!vis[s|w[j][i]]) vis[s|w[j][i]]=true,ans++; return; } Count(L+1,R,sum,s);Count(L+1,R,sum-a[L],s+(1<<L-1));Count(L+1,R,sum+a[L],s+(1<<L-1)); } int main() { freopen("program.in","r",stdin); freopen("program.out","w",stdout); scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]); return Dfs(1,n>>1),Count((n>>1)+1,n),printf("%d\n",ans-1),0; }
相关文章推荐
- 【BZOJ】2679 [Usaco2012 Open]Balanced Cow Subsets 折半搜索+状压
- bzoj 2679: [Usaco2012 Open]Balanced Cow Subsets 折半搜索
- BZOJ 2679: [Usaco2012 Open]Balanced Cow Subsets meet_in_the_middle / 折半搜索
- BZOJ2679: [Usaco2012 Open]Balanced Cow Subsets
- 【BZOJ】2679: [Usaco2012 Open]Balanced Cow Subsets
- BZOJ2679: [Usaco2012 Open]Balanced Cow Subsets
- BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针
- [Meet In Middle] BZOJ 2679 [Usaco2012 Open]Balanced Cow Subsets
- bzoj2679:[Usaco2012 Open]Balanced Cow Subsets
- BZOJ2679 : [Usaco2012 Open]Balanced Cow Subsets
- [USACO 2012OPEN] Balanced Cow Subsets(meet in the middle + DFS)
- JZOJ2935. 【USACO Open 2012 Gold Division】Balanced Cow Subsets
- bzoj2679 [Usaco2012 Open]Balanced Cow Subsets折半搜索
- BZOJ1646: [Usaco2007 Open]Catch That Cow 抓住那只牛
- 【BZOJ】3404: [Usaco2009 Open]Cow Digit Game又见数字游戏(博弈论)
- 【BZOJ 1647】[Usaco2007 Open]Fliptile 翻格子游戏 模拟、搜索
- 【博弈论】【SG函数】bzoj3404 [Usaco2009 Open]Cow Digit Game又见数字游戏
- 【BZOJ 1646】 [Usaco2007 Open]Catch That Cow 抓住那只牛
- [BZOJ] 1646: [Usaco2007 Open]Catch That Cow 抓住那只牛
- bzoj'1646: [Usaco2007 Open]Catch That Cow 抓住那只牛