[CF687C] The Values You Can Make - dp
Description
给出n,k,以及n个数字,选取若干个数字组成k ,在这若干个数字中选择一个子集, 问这个子集的和,可能的值有多少个。
Solution
设 (f[i][j][k]) 表示是否可以用前 (i) 个数组成大集合为 (j) 小集合为 (k) 的情况
#include <bits/stdc++.h>
using namespace std;
#define int long long
int f[2][1005][1005], c[505], n, k;
#define last f[(i - 1) & 1]
#define now f[(i)&1]
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> k;
for (int i = 1; i <= n; i++)
cin >> c[i];
f[0][0][0] = 1;
for (int i = 1; i <= n; i++)
{
memset(now, 0, sizeof now);
for (int j = 0; j <= k; j++)
{
for (int l = 0; l <= k; l++)
{
int x = c[i];
now[j][l] |= last[j][l];
now[j + x][l] |= last[j][l];
now[j + x][l + x] |= last[j][l];
}
}
}
vector<int> ans;
for (int i = 0; i <= k; i++)
if (f[n & 1][k][i])
ans.emplace_back(i);
cout << ans.size() << endl;
for (auto i : ans)
cout << i << " ";
}