题目:P1466 [USACO2.2] 集合 Subset Sums
题目描述
对于从1 ∼ n 1\sim n1∼n的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的。举个例子,如果n = 3 n=3n=3,对于{ 1 , 2 , 3 } \{1,2,3\}{1,2,3}能划分成两个子集合,每个子集合的所有数字和是相等的:
{ 3 } \{3\}{3}和{ 1 , 2 } \{1,2\}{1,2}是唯一一种分法(交换集合位置被认为是同一种划分方案,因此不会增加划分方案总数)
如果n = 7 n=7n=7,有四种方法能划分集合{ 1 , 2 , 3 , 4 , 5 , 6 , 7 } \{1,2,3,4,5,6,7 \}{1,2,3,4,5,6,7},每一种分法的子集合各数字和是相等的:
{ 1 , 6 , 7 } \{1,6,7\}{1,6,7}和{ 2 , 3 , 4 , 5 } \{2,3,4,5\}{2,3,4,5}
{ 2 , 5 , 7 } \{2,5,7\}{2,5,7}和{ 1 , 3 , 4 , 6 } \{1,3,4,6\}{1,3,4,6}
{ 3 , 4 , 7 } \{3,4,7\}{3,4,7}和{ 1 , 2 , 5 , 6 } \{1,2,5,6\}{1,2,5,6}
{ 1 , 2 , 4 , 7 } \{1,2,4,7\}{1,2,4,7}和{ 3 , 5 , 6 } \{3,5,6\}{3,5,6}
给出n nn,你的程序应该输出划分方案总数。
输入格式
输入文件只有一行,且只有一个整数n nn。
输出格式
输出划分方案总数。
输入输出样例 #1
输入 #1
7输出 #1
4说明/提示
【数据范围】
对于100 % 100\%100%的数据,1 ≤ n ≤ 39 1\le n \le 391≤n≤39。
翻译来自 NOCOW。
USACO 2.2
代码1(二维数组)
#include<bits/stdc++.h>usingnamespacestd;constintN=39+10;longlongn,V,v,f[N][(N*N+N)/2];intmain(){cin>>n;V=(1+n)*n/2;if(V%2)cout<<"0";else{V/=2;f[0][0]=1;for(inti=1;i<=n;i++){v=i;for(intj=0;j<=V;j++){f[i][j]=f[i-1][j];if(v<=j)f[i][j]+=f[i-1][j-v];}}cout<<f[n][V]/2;//{1,6,7} 和 {2,3,4,5}属于一个划分方式,但是会被计算两次}return0;}代码2(一维数组)
#include<bits/stdc++.h>usingnamespacestd;constintN=39+10;longlongn,V,v,f[(N*N+N)/2];intmain(){cin>>n;V=(1+n)*n/2;if(V%2)cout<<"0";else{V/=2;f[0]=1;for(inti=1;i<=n;i++){v=i;for(intj=V;j>=v;j--)f[j]+=f[j-v];}cout<<f[V]/2;}return0;}