动态规划,背包DP~
首先我们可以暴力选取材料的种类
c
c
c,
c
∈
[
1
,
n
]
c\in[1,n]
c∈[1,n],用 dp[i][j][k] 表示前 i 个数里选 j 个数且模数为 k 的最大值 sum,且 k=sum%c,则有如下的状态转移方程:
d
p
[
i
]
[
j
]
[
k
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
[
k
]
,
d
p
[
i
−
1
]
[
j
−
1
]
[
(
k
−
a
[
i
]
%
t
+
t
)
dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - 1][(k - a[i] \% t + t) % t] + a[i])
dp[i][j][k]=max(dp[i−1][j][k],dp[i−1][j−1][(k−a[i]%t+t)
AC代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, x, ans = INT64_MAX, a[105], dp[105][105][105];
int main() {
cin >> n >> x;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int t = 1; t <= n; t++) {
memset(dp, 0x80, sizeof(dp));
dp[0][0][0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= t; j++) {
for (int k = 0; k < t; k++) {
dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - 1][(k - a[i] % t + t) % t] + a[i]);
}
}
}
if (dp[n][t][x % t] > 0) ans = min(ans, (x - dp[n][t][x % t]) / t);
}
cout << ans;
return 0;
}