题意就是取 {1, 2, 3, ..., N} 的一个 subset,使得这个 subset 内元素的和为一个给定的值
(太久没做题的)我一开始竟然(想都没想)(并且数据范围都没看)(十分愚蠢地)写了递归,显然爆时间
再后来写了一个丑陋的 dp,第 i 个元素取: dp[i-1][j-i]; 不取:dp[i-1][j];
最后才意识到这是个01背包,求将背包填满的方案总数
谁来救救我吧(叹
AC代码如下:
(注释部分是最初写的那种 dp)
/*
PROB: subset
LANG: C++
ID: fan_0111
*/
#include <iostream>
#include <cstdio>
//long long dp[40][1000];
long long dp2[1000];
using namespace std;
int main() {
freopen("subset.in", "r", stdin);
freopen("subset.out", "w", stdout);
int n;
cin >> n;
int sum = n*(n+1)/2;
if (sum & 1) {
cout << 0 << endl;
}
else {
int tot = sum/2;
// dp[1][0] = dp[1][1] = 1;
// for (int i = 2; i <= n; ++i) {
// for (int j = 0; j <= tot; ++j) {
// dp[i][j] = dp[i-1][j];
// if (j-i >= 0) dp[i][j] += dp[i-1][j-i];
// }
// }
// cout << dp[n][tot]/2 << endl;
dp2[0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = tot-i; j >= 0; --j) {
if (dp2[j]) dp2[j+i] += dp2[j];
}
}
cout << dp2[tot]/2 << endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}