计蒜客--等和的分割子集

晓萌希望将 11 到 NN 的连续整数组成的集合划分成两个子集合,且保证每个集合的数字和是相等。例如,对于 N=3N=3,对应的集合 \{1,2,3\}{1,2,3} 能被划分成 \{3\}{3} 和 \{1,2\}{1,2} 两个子集合.

这两个子集合中元素分别的和是相等的。

对于 N=3N=3 ,我们只有一种划分方法,而对于 N=7N=7 时,我们将有 44 种划分的方案。

输入格式

输入包括一行,仅一个整数,表示 N(1 \le N \le 39)N(1N39)的值。

输出格式

输出包括一行,仅一个整数,晓萌可以划分对应 NN 的集合的方案的个数。当没法划分时,输出 00

样例输入
7
样例输出
4
用01背包的思想解决,开二维的dp,横坐标代表第i个数字,纵坐标j代表数字集合的和


#include<bits/stdc++.h>
using namespace std;
long long dp[42][1005]={0};
int main()
{
	long long i,n,sum=0;
	cin>>n;
	sum=(1+n)*n/2;
	if(sum%2)//如果是奇数则直接输出0
	cout<<'0'<<endl;
	else
	{
		for(int i=0;i<=n;i++)//初始化dp数组
		{
			dp[i][0]=1;
		}
	   for(int i=1;i<=n;i++)
	   {
	   	  for(int j=1;j<i;j++)//在小于i的情况下直接继承dp[i-1][j]
	   	   {
	   		  dp[i][j]=dp[i-1][j];
		   }
	   	  for(int j=i;j<=sum/2;j++)
	   	   {
	   		  dp[i][j]=dp[i-1][j]+dp[i-1][j-i];//dp[i][j]=上一层的方案数+上一层数字和为i-j的方案数
	       }
	  }
	 
	   cout<<dp[n][sum/2]/2;//因为等分集合是成对的所以除以2
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值