Problem:
http://ace.delos.com/usacoprob2?a=GDaP3qeGiYp&S=subset
My Answer:
/*
ID:iby071
LANG:C++
TASK:subset
*/
#include<iostream>
#include<fstream>
using namespace std;
int main()
{ ifstream fin("subset.in");
ofstream fout("subset.out");
int n,sum,high;
unsigned long int *dp;
fin>>n;
sum=(1+n)*n>>1; //>>1即除以2
if((sum&1)==1){fout<<'0'<<endl;return 0;} //&1即取个位
high=sum>>1;
dp=new unsigned long int [high+1];
for(int i=0;i<high+1;++i)
dp[i]=0;
dp[0]=1;
for(int i=1;i<=n;++i)
for(int j=high;j>=i;--j)
dp[j]=dp[j]+dp[j-i]; //j>i情况下,前i项和为j的组合方式书dp[(当前i下)j]=dp[(i-1情况下)j]+dp[(i-1情况下)j-i]
fout<<(dp[high]>>1)<<endl; //每一种子集对应的组合方式与它的补集对应的组合方式重复,故除以2
return 0;
}