基础 DP 题。
定义 \(f_{i,j,k}\) 表示从第一行走到 \((i,j)\),且数字总和模 \(p\) 等于 \(k\)。
转移方程为:
\[f_{i+1,j-1,(k+a_{i+1,j-1})\bmod p}=\max (f_{i,j,k}+a_{i+1,j-1}) \]\[f_{i+1,j+1,(k+a_{i+1,j+1})\bmod p}=\max(f_{i,j,k}+a_{i+1,j+1}) \]同时还需要定义 \(g_{i,j,k}\) 表示当前状态是由哪一种转移过来的。
注意边界情况。
复杂度 \(O(n^2)\)。
code:
#include<bits/stdc++.h>
using namespace std;
const int N=100+5,inf=INT_MAX/2;
int n,m,p,f[N][N][11],a[N][N],g[N][N][11];
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>m>>p;++p;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
char x;cin>>x;
a[i][j]=x-'0';
for(int k=0;k<p;++k)f[i][j][k]=-inf;
}
}
for(int j=1;j<=m;++j)f[1][j][a[1][j]%p]=a[1][j];
for(int i=1;i<n;++i){
for(int j=1;j<=m;++j){
for(int k=0;k<p;++k){
int tk=(k+a[i+1][j-1])%p,val=f[i][j][k];
if(j>1&&f[i+1][j-1][tk]<val+a[i+1][j-1]){
f[i+1][j-1][tk]=val+a[i+1][j-1];
g[i+1][j-1][tk]=1;
}
tk=(k+a[i+1][j+1])%p;
if(j<m&&f[i+1][j+1][tk]<val+a[i+1][j+1]){
f[i+1][j+1][tk]=val+a[i+1][j+1];
g[i+1][j+1][tk]=0;
}
}
}
}
int w=1;
for(int j=1;j<=m;++j){
if(f[n][j][0]>f[n][w][0]){
w=j;
}
}
if(f[n][w][0]<0){
cout<<-1<<endl;
return 0;
}
cout<<f[n][w][0]<<endl;
cout<<w<<endl;
int i=n,j=w,k=0;
while(i>=2){
if(g[i][j][k]){
cout<<"R";
k=(k-a[i][j]%p+p)%p;--i;++j;
}else {
cout<<"L";
k=(k-a[i][j]%p+p)%p;--i;--j;
}
}
return 0;
}
标签:11,int,题解,bmod,CF41D,max,tie
From: https://www.cnblogs.com/HQJ2007/p/17561328.html