题解:CF1433F Zero Remainder Sum
zhangxuanhui · · 题解
前言
这么裸的DP,模拟赛时本蒟蒻竟然没有看出来!!!
正文
题目回忆录
题意
给定一个
保证答案合法,且和最大,我们考虑DP,但当前的区间是一个二维矩阵,如果直接设四维状态,感觉又不太好理解,所以我们可以分行处理,设
同时为了行与行之间的状态好转移,我们用一个一维数组
我们考虑对于行与行之间的状态转移,令
这样本题就基本解决了。
#include<bits/stdc++.h>
#define pir pair<int,int>
using namespace std;
typedef long long ll;
const int N=88;
int n,m,k,a[N],f[N][N],g[N][N],F[N];
void work(){
memset(f,0xef,sizeof(f));
memset(F,0xef,sizeof(F));
f[0][0]=0;
for(int i=1;i<=m;i++){
scanf("%d",&a[i]);
for(int cnt=i-1;cnt>=0;cnt--){
for(int j=0;j<k;j++){
f[cnt+1][(j+a[i])%k]=max(f[cnt+1][(j+a[i])%k],f[cnt][j]+a[i]);
}
}
}
for(int cnt=0;cnt<=m/2;cnt++) for(int j=0;j<k;j++) F[j]=max(F[j],f[cnt][j]);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
memset(g,0xef,sizeof(g));
g[0][0]=0;
for(int i=1;i<=n;i++){
for(int x=0;x<k;x++) g[i][x]=g[i-1][x];
work();
for(int x=0;x<k;x++)
for(int y=0;y<k;y++) g[i][(x+y)%k]=max(g[i][(x+y)%k],F[y]+g[i-1][x]);
}
printf("%d",g[n][0]);
}
//code subimission time---Zero Remainder Sum---12.10
感谢同机房@chenyuze_2029 大佬的协助。