codeforce 1433F - Zero Remainder Sum (dp)

题目链接:https://codeforces.com/problemset/problem/1433/F

\(dp[i][l][j][k]\)表示第 i 行,前 l 列,选 j 个数, 模 d 余 k 的最大方案数
注意初始化的条件
(比赛的时候打错一个字母调到心态爆炸,不要随意更换循环的字母

#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;
}
posted @ 2020-10-21 01:09  Tartarus_li  阅读(128)  评论(0编辑  收藏  举报