给了你 n 个数,希望你从这 n 个数中找到3个数,使得这三个数的和是 K 的倍数,且这个和最大。
思路
f[i][j][k] 表示从前i个数选j个数,且j个数之和模K为k的最大和,有两种决策:
- 选第i个数:
f[i][j][k]=max(f[i][j][k], f[i-1][j][k])
- 不选第i个数:
f[i][j][k]=max(f[i][j][k], f[i-1][j-1][mod]+a[i]);
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5, M=1e3+5, inf=0x7f;
int f[2][4][M], a[N], b[N];
int mod(int x, int K) {
return (x%K+K)%K;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,K,st=1; cin>>n>>K;
memset(f, -inf, sizeof f), f[0][0][0]=0;
for (int i=1; i<=n; i++) cin>>a[i], b[i]=a[i]%K;
for (int i=1; i<=n; i++, st^=1)
for (int j=0; j<4; j++)
for (int k=0; k<K; k++) {
f[st][j][k]=max(f[st][j][k], f[st^1][j][k]);
if (j) f[st][j][k]=max(f[st][j][k], f[st^1][j-1][mod(k-b[i], K)]+a[i]);
}
cout<<f[st^1][3][0];
return 0;
}