codeforces 1433F - Zero Remainder Sum (dp)
题目链接:https://codeforces.com/problemset/problem/1433/F
注意dp前初值的处理
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 71;
int n,m,d;
ll a[maxn][maxn];
ll dp[maxn][maxn][maxn][maxn]; // 第 i 行,取 j 个,和模 k 余 p 的最大值
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
memset(dp,-1,sizeof(dp));
n = read(), m = read(), d = read();
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
a[i][j] = read();
}
}
for(int i=0;i<=m;++i){
dp[1][i][0][0] = 0;
}
for(int i=1;i<=n;++i){
for(int j=0;j<=m;++j){
dp[i][j][0][0] = 0;
}
for(int p=0;p<=m;++p){
for(int j=0;j<=m/2;++j){
for(int k=0;k<d;++k){
dp[i][p][0][k] = max(dp[i][p][0][k],dp[i-1][m][j][k]);
}
}
}
for(int l=1;l<=m;++l){
for(int j=1;j<=l;++j){
for(int k=0;k<d;++k){
if(dp[i][l-1][j-1][k]!=-1){
dp[i][l][j][(k+a[i][l])%d] = max(dp[i][l][j][(k+a[i][l])%d],dp[i][l-1][j-1][k] + a[i][l]); // 选
}
if(dp[i][l-1][j][k]!=-1) dp[i][l][j][k] = max(dp[i][l][j][k],dp[i][l-1][j][k]);// 不选
}
}
}
}
ll ans = 0;
for(int j=0;j<=(m/2);++j) ans = max(ans,dp[n][m][j][0]);
printf("%lld\n",ans);
return 0;
}