【BZOJ】2679 [Usaco2012 Open]Balanced Cow Subsets 折半搜索+状压
2017-10-27 20:09
477 查看
题目传送门
第一眼看到这题,以为可以直接大力搜索,T了一发以后发现时间复杂度为O(320),于是就想折半搜索。
然而直接折半搜索WA了一发以后我停下了盲目的敲代码,仔细思考了题目。造了一组数据:“6 88 36 36 7 95 24”,发现{88,36,7}与{36,95}有两种组合情况,但是答案只会被加一次。
于是想到状压,判断两个相等的集合内取了哪些数,开个bool数组去一下重即可。
附上AC代码:
但是!!!
上述代码可能TLE,实测BZOJ数据跑出来需要10576ms,卡时限AC……QAQ
于是想到计算答案的那个搜索调用STL次数太多,需要用一些常数较小的数据结构来优化一下。由map想到了手打hash map。
于是orz zzk,大佬教我打hash map,太强啦。
附上AC代码:
第一眼看到这题,以为可以直接大力搜索,T了一发以后发现时间复杂度为O(320),于是就想折半搜索。
然而直接折半搜索WA了一发以后我停下了盲目的敲代码,仔细思考了题目。造了一组数据:“6 88 36 36 7 95 24”,发现{88,36,7}与{36,95}有两种组合情况,但是答案只会被加一次。
于是想到状压,判断两个相等的集合内取了哪些数,开个bool数组去一下重即可。
附上AC代码:
# pragma GCC optimize "O3" # pragma G++ optimize "O3" #include <cstdio> #include <algorithm> #include <map> #include <vector> using namespace std; map <int,vector <int> > f; int n,a[21],ans; bool b[1048580]; inline void so1(int l,int r,int sum,int s){ if (l>r){ f[sum].push_back(s); return; } so1(l+1,r,sum,s); so1(l+1,r,sum+a[l],s+(1<<l-1)); so1(l+1,r,sum-a[l],s+(1<<l-1)); return; } inline void so2(int l,int r,int sum,int s){ if (l>r){ for (int i=0; i<f[-sum].size(); ++i) if (!b[s|f[-sum][i]]) b[s|f[-sum][i]]=1,++ans; return; } so2(l+1,r,sum,s); so2(l+1,r,sum+a[l],s+(1<<l-1)); so2(l+1,r,sum-a[l],s+(1<<l-1)); return; } int main(void){ scanf("%d",&n); for (int i=1; i<=n; ++i) scanf("%d",&a[i]); so1(1,n>>1,0,0),so2((n>>1)+1,n,0,0),printf("%d\n",ans-1); return 0; }
但是!!!
上述代码可能TLE,实测BZOJ数据跑出来需要10576ms,卡时限AC……QAQ
于是想到计算答案的那个搜索调用STL次数太多,需要用一些常数较小的数据结构来优化一下。由map想到了手打hash map。
于是orz zzk,大佬教我打hash map,太强啦。
附上AC代码:
#include <cstdio> #include <vector> using namespace std; typedef long long ll; const int m=0x7fffffff,mod=999917; int n,a[21],ans; int num,h[mod],nt[59050]; vector <int> f[59050]; ll w[59050]; bool b[1<<20]; inline void ist(ll sum,int s){ for (int i=h[(sum+=m)%mod]; i; i=nt[i]) if (w[i]==sum) return f[i].push_back(s); return (void)(w[++num]=sum,f[num].push_back(s),nt[num]=h[sum%mod],h[sum%mod]=num); } inline int find(ll sum){ for (int i=h[(sum+=m)%mod]; i; i=nt[i]) if (w[i]==sum) return i; return 0; } inline void so1(int l,int r,int sum=0,int s=0){ if (l>r) return ist(sum,s); return so1(l+1,r,sum,s),so1(l+1,r,sum+a[l],s+(1<<l-1)),so1(l+1,r,sum-a[l],s+(1<<l-1)); } inline void so2(int l,int r,int sum=0,int s=0){ if (l>r){ for (int i=find(-sum),j=0; j<f[i].size(); ++j) if (!b[s|f[i][j]]) b[s|f[i][j]]=1,++ans; return; } return so2(l+1,r,sum,s),so2(l+1,r,sum+a[l],s+(1<<l-1)),so2(l+1,r,sum-a[l],s+(1<<l-1)); } int main(void){ scanf("%d",&n); for (int i=1; i<=n; ++i) scanf("%d",&a[i]); return so1(1,n>>1),so2((n>>1)+1,n),printf("%d\n",ans-1),0; }
相关文章推荐
- BZOJ 2679: [Usaco2012 Open]Balanced Cow Subsets meet_in_the_middle / 折半搜索
- bzoj 2679: [Usaco2012 Open]Balanced Cow Subsets 折半搜索
- 【折半搜索】BZOJ2679(Usaco2012 Open)[Balanced Cow Subsets]题解
- BZOJ2679 : [Usaco2012 Open]Balanced Cow Subsets
- BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针
- 【BZOJ】2679: [Usaco2012 Open]Balanced Cow Subsets
- BZOJ2679: [Usaco2012 Open]Balanced Cow Subsets
- bzoj2679:[Usaco2012 Open]Balanced Cow Subsets
- [Meet In Middle] BZOJ 2679 [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折半搜索
- 【BZOJ 1647】[Usaco2007 Open]Fliptile 翻格子游戏 模拟、搜索
- bzoj 3404: [Usaco2009 Open]Cow Digit Game又见数字游戏(SG函数)
- BZOJ 1646[Usaco2007 Open]Catch That Cow 抓住那只牛 双向bfs版
- 【BZOJ】3404: [Usaco2009 Open]Cow Digit Game又见数字游戏(博弈论)
- BZOJ_1623:_[Usaco2008_Open]_Cow_Cars_奶牛飞车_(贪心)
- 【博弈论】【SG函数】bzoj3404 [Usaco2009 Open]Cow Digit Game又见数字游戏
- [BZOJ] 1646: [Usaco2007 Open]Catch That Cow 抓住那只牛