//usaco training-Subset Sums /* * 题目类型:DP-背包 * 状态表示:DP[i][j]表示前i个数放入背包中达到值j的方案数 * 对于第i个数 有两种方案:放 和 不放 得: * 状态转移方程:DP[i][j]=DP[i-1][j]+DP[i-1][j-i](j>=i) * 初始:DP[0][0]=1 * wa ac * 此题的方案数目超过int型范围,应为long long */ /* Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 5372 KB] Test 2: TEST OK [0.000 secs, 5372 KB] Test 3: TEST OK [0.000 secs, 5372 KB] Test 4: TEST OK [0.000 secs, 5372 KB] Test 5: TEST OK [0.000 secs, 5372 KB] Test 6: TEST OK [0.000 secs, 5372 KB] Test 7: TEST OK [0.000 secs, 5372 KB] All tests OK. */ #include <iostream> #include <fstream> using namespace std; long long dp[100][3000]; int main(void) { int i,j,k,N,sum; ifstream fin("subset.in"); ofstream fout("subset.out"); fin>>N; sum=N*(N+1)/2; if(sum&1) fout<<'0'<<endl; else{ dp[0][0]=1; for(i=1; i<=N; ++i) for(j=0; j<=sum/2; ++j) { dp[i][j]=dp[i-1][j]; if(j>=i) dp[i][j]+=dp[i-1][j-i]; } fout<<dp[N][sum/2]/2<<endl; } return 0; }