等和的分隔子集
晓萌希望将 1 到 N 的连续整数组成的集合划分成两个子集合,且保证每个集合的数字和是相等。例如,对于 N = 3,对应的集合 {1, 2, 3} 能被划分成 {3} 和{1, 2} 两个子集合。
这两个子集合中元素分别的和是相等的。
对于N=3,我们只有一种划分方法,而对于N=7 时,我们将有 4 种划分的方案。
输入格式
输入包括一行,仅一个整数,表示 N 的值 (1≤N≤39)。
输出格式
输出包括一行,仅一个整数,晓萌可以划分对应 N 的集合的方案的个数。当没发划分时,输出 0。
样例输入
7
样例输出
4
代码
#include<bits/stdc++.h>
using namespace std;
long long dp[50][50005];
int n,ans;
int main() {
cin>>n;
int s=(1+n)*n/2;
if(s & 1) {
cout<<0<<endl;
return 0;
}
//s & 1表示s是否为奇数,如果是奇数就肯定不能一分为二,
int ss=s/2;
dp[0][0]=1;
for(int i=1;i<ss;i++) {
dp[0][i]=0;//当背包容量为i,前零个数的方案为1
}
for(int i=1;i<=n;i++) {
for(int h=0;h<=ss;h++) {
if(h<i) dp[i][h]=dp[i-1][h];//当h<i时,意味着背包需求为h,但是我i已经大于h了,意味着肯定不能把i放进背包,所以当前情况为上一种情况
else {
dp[i][h]=dp[i-1][h]+dp[i-1][h-i];
//要么放进去要么不放进去
}
}
}
cout<<dp[n][ss]/2<<endl;//除以二是有重复的
return 0;
}
其他代码求解
#include<bits/stdc++.h>
using namespace std;
long long dp[2][50005];
int n,sum;
int main() {
cin>>n;
sum=n*(n+1)/2;
dp[0][0]=1;
if