题目大意:
将1到N的连续整数组成的集合划分成两个子集合,且保证每个集合的数字和是相等的。
例如,输入N=3,对应的集合{1,2,3} 可以被划分为{3},{1,2}两个子集合,这两个子集合中元素分别的和是相等的。输入7,输出4
思路:
首先1,2,3……N所有元素的和为 S= N*(N+1)/2, 如果S不能被2整除,那么一定不能划分,否则各个集合里面的元素之和为 S = N*(N+1)/4,下面运用动态规划的思想,令count[i] 表示 和为 i 的方案数目,那么 count[j] = count[j] + count[j-i] , 表示和为 j 的方案数,等于原先的值 加上 和为 j-i 的方案数。 也就是说,没有加 i 之前的方案数 现在加上i之后,和变为 j, 那么和为j的方案数也应该加上 和为j-i的方案数,有点绕。。。
很经典的动态规划的例子,刚开始做竟然没想起来。
#include <iostream>
using namespace std;
#define N 40
int main(){
int n,s;
cin>>n;
int count[400]; //该数组count[i]表示和为i的方案数
memset(count,0,sizeof(count));
s = n*(n+1)/2;
if(s%2!=0)
cout<<0<<endl;
s = s/2;
count[0] = 1;
for(int i=1;i<=n;i++){
for(int j=s;j>=i;j--){
count[j] += count[j-i];
}
}
cout<<count[s]/2<<endl;
return 0;
}