【洛谷】1466 集合 Subset Sums 折半搜索

来源:互联网 发布:尚学堂oa源码 编辑:程序博客网 时间:2024/06/17 21:30

题目传送门

这题的直观感受就是折半搜索,但是无从下手……有点小尴尬……

设等差数列求和之后的和为sum,如果sum为奇数显然无法分成两半,直接输出0;否则必定可以分成两个子集。

考虑折半搜索,对所有出现过的值记录次数,然后直接利用乘法原理统计答案即可。

p.s.这题的答案可能爆int,注意答案用long long来存。

又p.s.这题其实直接用背包来做就好了……

附上AC代码:

#include <cstdio>using namespace std;int n,sum,f[2][800];long long ans;inline void so(int l,int r,int w,int *f){    if (l>r) return (void)(++f[w]);    so(l+1,r,w+l,f),so(l+1,r,w,f);    return;}int main(void){    scanf("%d",&n),sum=n*(n+1)/2;    if (sum&1) return puts("0"),0;    sum/=2,so(1,n>>1,0,f[0]),so((n>>1)+1,n,0,f[1]);    for (int i=0; i<=sum; ++i) ans+=1ll*f[0][i]*f[1][sum-i];    return printf("%ld\n",ans/2),0;}
原创粉丝点击