f[i][j]表示挑选前i个物品后,价值%k=j的最大价值
由01背包转移思想,可得转移方程f[i][j]=max(f[i-1][j],f[i-1][((j-w[i])%k+k)%k]+w[i])
注意初始需要将f[0][1~k]置为-INF,初始不能从此状态转移
#include<iostream>
#include<cstring>
using namespace std;
int n,k;
const int INF=0x3f3f3f3f;
int f[105][105],w[105];
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=k;i++) f[0][i]=-INF;
for(int i=1;i<=n;i++)
for(int j=0;j<k;j++)
f[i][j]=max(f[i-1][j],f[i-1][((j-w[i])%k+k)%k]+w[i]);
cout<<f[n][0];
}