题目

image-1671786520627

题解

朴素dp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10, M=1010;

int n, m;
int a[N];
int f[N][5][M];

signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d", &a[i]);

    memset(f, -0x3f, sizeof f);
    for(int i=0;i<=n;i++) f[i][0][0]=0;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=3;j++)
            for(int k=0;k<m;k++)
                f[i][j][k]=max(f[i-1][j][k], f[i-1][j-1][((k-a[i])%m+m)%m]+a[i]);

    int ans=-1;
    for(int i=1;i<=n;i++) ans=max(ans, f[i][3][0]);
    cout<<ans<<endl;
}

作者:白之月
链接:https://www.acwing.com/solution/content/43862/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

优化

只有考虑余数

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=1010;
int n,m;
vector<int> a[N];
int f[4][N];
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        a[x%m].push_back(x);
    }
    memset(f,-0x3f,sizeof f);
    f[0][0]=0;
    for(int i=0;i<m;i++){
        sort(a[i].begin(),a[i].end());
        reverse(a[i].begin(),a[i].end());
        for(int u=0;u<a[i].size()&&u<=3;u++){
            int x=a[i][u];
            for(int j=3;j>=1;j--){
                for(int k=0;k<m;k++){
                    f[j][k]=max(f[j][k],f[j-1][(k-x%m+m)%m]+x);
                }
            }
        }
    }
    cout<<f[3][0]<<endl;
    return 0;
}