HLG 1541 集合划分【01背包】
题意: 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的。举个例子,如果N=3,
对于{1,2,3}能划分成两个子集合,每个子集合的所有数字和是相等的:{3} 和 {1,2}
给出一个 N 值,问最多能划分成多少种等值的集合。
分析:每个数字只用到一次,每种情况的存在数可以由之前的存在的数来递推得到,01背包的变形。
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) long long f[50000]; int main() { long long n,i,j,v; while(scanf("%lld",&n)!=EOF) { if(n==0) break; v=n*(n+1)/2; if(v%2==1) { printf("0\n"); continue; } clr(f); f[0]=1; v/=2; for(i=1;i<=n;i++) for(j=v;j>=i;j--) f[j]+=f[j-i]; printf("%lld\n",f[v]/2); } return 0; }