P1466 [USACO2.2] 集合 Subset Sums
P1466 USACO2.2 集合 Subset Sums
毫无思路
如果不告诉我这题是DP题,我一定会爆搜。
看了题解,很妙。
居然也能套背包板子。
定义F[i][j]
为在前\(i\)个数中选择一些数其和为\(j\)的方案总数。
显然转移方程F[i][j] = F[i - 1][j] + F[i - 1][j - i]
要么不选当前第\(i\) 个数,要么选。
最后答案输出F[sum/2]
即可。
代码实现
显然能优化空间
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n, sum;
int F[1010];
int main()
{
cin >> n;
sum = ((n + 1) * n) / 2;
if (sum % 2)
{
cout << 0;
return 0;
}
F[1] = 1;
F[0] = 1;
for (int i = 2; i <= n; i++)
{
for (int j = sum; j >= 0; j--)
{
if (j > i)
F[j] = F[j] + F[j - i];
}
}
cout << F[sum / 2];
return 0;
}