abc281D 最大的能被d整除的k数之和

题面:给定数组A[n],从中取出k个元素,使元素之和为d的倍数。求满足条件的元素之和的最大值。
范围:1<=k<=n<=100; 1<=d<=100; 0<=A[i]<=1E9

思路:记dp[i][j][k]表示前i个数里选了j个,并且元素之和除d的余数为k,按选与不选两种情况递推,这里用的刷表法。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)

const int N = 105;
const int inf = 1E18;
int n, k, d, a[N], dp[N][N][N];
void solve() {
    cin >> n >> k >> d;
    rep(i,1,n) cin >> a[i];
    rep(i,0,N-1) rep(j,0,N-1) rep(k,0,N-1) {
        dp[i][j][k] = -inf;
    }
    dp[0][0][0] = 0;
    rep(i,0,n-1) rep(j,0,i) rep(k,0,d-1) {
        if (dp[i][j][k] == -inf)
            continue;
        dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k]);
        int z = (dp[i][j][k] + a[i+1]) % d;
        dp[i+1][j+1][z] = max(dp[i+1][j+1][z], dp[i][j][k]+a[i+1]);
    }
    if (dp[n][k][0] == -inf)
        cout << "-1\n";
    else
        cout << dp[n][k][0] << "\n";
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}
posted @ 2024-03-09 21:46  chenfy27  阅读(3)  评论(0编辑  收藏  举报