USACO subset

/*
ID:kevin_s1
PROG:subset
LANG:C++
*/
//参考了nocow,动态规划= = F[i][j]表示前i个数中取值的和为j的方案数,F[i][j] = F[i-1][j] + F[i-1][j-i] (j >= i)  F[i][j] = F[i-1][j] (j < i)
#include<stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

int result;
int sum;
long long F[40][900];
long long i,k,l,j,m,n,s;
long long edge(int x);
int DP()
{
	int i,j,k;
	for(i=2;i<=n;i++)
		for(j=0;j<=edge(i);j++)
		{
			if(j>=i)
				F[i][j]=F[i-1][j]+F[i-1][j-i];
			else if(j<i)
				F[i][j]=F[i-1][j];
		}
 
	return F[n][sum];		
}

void open()
{
	freopen("subset.in", "r", stdin);
	freopen("subset.out", "w", stdout);
}

long long edge(int x)
{
	return ((x+1)*x)/2;
}

int main()
{
	open();
	cin>>n;
	sum = ((n+1)*n)/2;
	if(sum&1==1)
	{
		cout<<"0"<<endl;
		return 0;
	}
	sum /= 2;
	F[1][1]=1;
	F[1][0]=1;
	result = DP();
	printf("%lld\n",result/2);
	return 0;
}

你可能感兴趣的:(USACO subset)