2021-03-01

动态规划,背包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;
}
上一篇:APS 105


下一篇:105. 从前序与中序遍历序列构造二叉树(深搜)