01背包的基本框架。。外面套一层枚举个数。。。小一类题型。
1 这里需要自己枚举 最终目标物品的个数。。因为这里涉及%个数 的值 所以
只有先确定个数 我们才dp。。不然数组开多大你都不知道
2 这里就是目标sum%cnt=X%cnt 。。这也是常见的一种关系。
题目链接
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128_t
#define ar array<int, 2>
#define arr array<int, 3>
int n, m, k, inf = 1LL << 61, mod = 998244353;// 1e9+7;
const int N = 5e5 + 50;
void solve() {
cin >> n >> m;
int a[n];
for (int &x : a)
cin >> x;
int ans = inf;
for (int k = 1; k <= n; ++k) {//枚举最终个数
vector f(k + 1, vector<int>(k, -1));
f[0][0] = 0;
for (int x : a)// 枚举物品
for (int i = k; i; i--)//下面两层枚举状态容器
for (int j = 0; j < k; ++j) {
if (~f[i - 1][j])
f[i][(j + x) % k] = max(f[i - 1][j] + x , f[i][(j + x) % k]);
}
if (f[k][m % k] > 0)//这边要判定下是不是 合法。
ans = min(ans, (m - f[k][m % k]) / k);
}
cout << ans;
};
// 就是选择k个物品。。他总和是多少。。%k的。。要和x%k相等。。。
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout << fixed << setprecision(15);
#ifdef DEBUG
freopen("../1.in", "r", stdin);
#endif
//init_f();
//init();
//expr();
// int T; cin >> T; while(T--)
solve();
return 0;
}