https://codeforces.com/problemset/problem/1433/F
You are given a matrix aa of size n \times mn×m consisting of integers.
You can choose no more than \left\lfloor\frac{m}{2}\right\rfloor⌊
2
m
⌋ elements in each row. Your task is to choose these elements in such a way that their sum is divisible by kk and this sum is the maximum.
In other words, you can choose no more than a half (rounded down) of elements in each row, you have to find the maximum sum of these elements divisible by kk.
Note that you can choose zero elements (and the sum of such set is 00).
#include<iostream>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<unordered_map>
#include<iomanip>
#define ll long long
#define ull unsigned long long
#define gg ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define m_p make_pair
#define pi acos(-1)
using namespace std;
const int N = 1e6 + 5;
const int M = 5e5 + 5;
const double eps = 1e-4;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9+7;
int n, m, k, dp[80][80][80][80];//前i行, 第i行前j个,选了k个 , 模数为r的最大数 ///开long long 会MLE
int a[80][80];
void solve()
{
memset(dp, -1, sizeof dp);//-1表示没有余数为r的情况
dp[1][0][0][0] = 0;//一个不选为0
cin>>n>>m>>k;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
cin>>a[i][j];
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
for(int w = 0; w <= min(j, m/2); w++)//已选多少个
{
for(int u = 0; u < k; u++)//模数
{
dp[i][j][w][u] = max(dp[i][j-1][w][u], dp[i][j][w][u]);//不选a[i][j]
if(w && dp[i][j-1][w-1][u] != -1)//判断是否在之前余数为u时可选a[i][j]
dp[i][j][w][(u + a[i][j]) % k] = max(dp[i][j][w][(u + a[i][j]) % k], dp[i][j - 1][w-1][u] + a[i][j]);
}
for(int ii = 0; ii < k; ii++)
dp[i+1][0][0][ii] = max(dp[i][j][w][ii], dp[i+1][0][0][ii]);///将i行信息转移给下一行一个未选的情况
}
}
}
cout<<dp[n+1][0][0][0];
}
signed main()
{
gg;
ll t = 1;
// cin>>t;
while(t--)
solve();
return 0;
}