题解 P1466 【集合 Subset Sums】
题解by:redbag
原题解地址:http://redbag.duapp.com/?p=1197
n个数的总和为sum:=n*(n+1)shr 1,当且仅当sum为偶数的时候才有解,sum为奇数时直接输出0并且退出程序;然后每个数只有2种情况,放在第一个集合和不放在第一个集合。于是就是简单的01背包问题了。简单的分析见图
图)
代码:
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#define LL unsigned long long
using namespace std;
int sum/*1~n的和*/,n;
int f[40][800];
int i,j;
int main()
{
freopen("subset.in","r",stdin);
freopen("subset.out","w",stdout);
scanf("%d",&n);
sum=(n*(n+1))/2;//算出1~n的和。
if (sum%2==1)//仅当sum为偶数的时候才有解
{
printf("0\n");//因为分成的2份和要相等
return 0;
}
f[1][1]=1;//1中取任意个数的数使和为1的情况
f[1][0]=1;//1中取任意个数的数使和为0的情况
for (i=2;i<=n;i++)//1的情况已经算完了,所以从2开始
{
for (j=0;j<=sum;j++)
{
if (j>i)//有取这个数和不取两种情况
f[i][j]=f[i-1][j]+f[i-1][j-i];
else f[i][j]=f[i-1][j];//只能不取了
}
}
printf("%d\n",f[n][sum/2]);
return 0;
}