题目要求
问题描述:将1到N的连续整数组成的集合划分为两个子集合,且保证每个集合的数字和相等。例如,对于N=4,对应的集合{1,2,3,4},能被划分为{1,4}、{2,3}两个集合,使得1+4=2+3,且划分方案只有此一种。编程实现给定任一正整数N(1<=N<=39),输出其符合题意的划分方案数。
样例输入1:3
样例输出1:1 (可划分为{1,2}、{3})
样例输入2:4
样例输出2:1 (可划分为{1,3}、{2,4})
样例输入3:7
样例输出3:4 (可划分为{1,6,7}、{2,3,4,5},或{1,2,4,7}、{3,5,6},或{1,3,4,6}、{2,5,7},或{1,2,5,6}、{3,4,7})
解决方案
此题的解决方案有多种,但基本思想是动态规划。
首先,观察子集合的和。
对于任一正整数N,集合{1,2,3...N}的和为:
,
那么将集合S划分为两个和相等的子集合后,其子集合C中的整数和必为:
。
例如对于正整数4,集合{1,2,3,4}的和为S=4*(4+1)/2=10,那么将其划分为和相等的两个子集合后,其子集合C中的整数和为sum=S/2=5。
于是,此题就转化为在集合{1,2,3...N}中,任意选取k个数,使其和为N*(N+1)/4的问题,换句话说,就是限制子集合和为N(N+1)/4时,集合{1,2,3...,N}中可提供的整数选取方案数。
此描述隐含两个条件:第一,N*(N+1)除以4必须为整数,否则无法选取;第二,在选出k个数的所有方案中,每个方案都有其互补的方案。还是拿整数4举例,对于集合{1,2,3,4},任选k个数,使其和为4*(4+1)/4=5时,有两种方案{1,4}和{2,3},这两种方案互补构成所有整数集合,并生成一种集合划分方案。由此可得出,将选取k个数的所有方案数除以2,就是集合N划分为相等的子集合的方案数。
接下来,从集合S中往出选k个数,使其和为N*(N+1)/4,看有多少种选取方案。
给定集合S={1,2,3...,N},我们将其一字排开,挨个