将1~n分成2组,使2组和相等。求有多少种分法。
搜索貌似会炸,就用dp。
f[i][k]表示最后一个数是i,和为k的方案数。
f[j][k]=f[1][k-j]+f[2][k-j]+...+f[j-1][k-j]
注意一点,输出“0”当且仅当(1+n)*n/2为奇数。第一次提交时脑抽以为是当n为偶数。
用递推写的。
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
int b[40],f[40][781];
int main()
{
freopen("subset.in","r",stdin);
freopen("subset.out","w",stdout);
int n=read();
for(int i=1;i<=n;++i) b[i]=(1+i)*i/2;
int m=b[n]/2;
if(b[n]%2==1){
printf("0\n");
return 0;
}
f[1][1]=1;
for(int i=1;i<n;++i)
for(int k=1;k<=b[i];++k){
if(!f[i][k]) continue;
for(int j=i+1;j<=n;++j){
if(k+j>m) break;
f[j][k+j]+=f[i][k];
}
}
int ans=0;
for(int i=1;i<=n;++i) ans+=f[i][m];
printf("%d\n",ans);
}