题意
这道题是很简单的线性dp , 绿题 , 首先我们肯定要做二维的dp , 表示横坐标和纵坐标 , 但是题目又给了一个只有整除(k + 1) 的才能作为方案数 , (洛谷上的题解都是求总和为多少[没有意义的时间复杂度]),我的思路是横坐标为i, 纵坐标为j , 和 模 (k + 1) 为 z 的最大和 。
时间复杂度一个完美的时间复杂度(n * m * k ) 。
代码
// Problem: CF41D Pawn
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF41D
// Memory Limit: 250 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
const int N = 1e2 + 10 , M = 15 ;
int f[N][N][M] ;
int dx[] = {0 , 1 , 0 , -1} ;
int dy[] = {1 , 0 , -1 , 0} ;
char s[N][N] ;
int n , m , k ;
int path[N] ;
int read()
{
int res = 0 , flag = 1 ;
char c = getchar() ;
while(!isdigit(c))
{
if(c == '-') flag = -1 ;
c = getchar() ;
}
while(isdigit(c))
{
res = (res << 1) + (res << 3) + (c ^ 48) ;
c = getchar() ;
}
return res * flag ;
}
int get(int x)
{
return (x % (k + 1) + (k + 1)) % (k + 1) ;
}
int main(void)
{
memset(f , -0x3f , sizeof f) ;
n = read() , m = read() , k = read() ;
for(int i = 1 ; i <= n ; i ++)
scanf("%s" , s[i] + 1) ;
for(int i = 0 ; i <= m + 1 ; i ++) f[n + 1][i][0] = 0 ;
for(int i = n ; i ; i --)
for(int j = 1 ; j <= m ; j ++)
for(int p = 0 ; p <= k ; p ++)
{
int q = get(p - (s[i][j] - '0')) ;
f[i][j][p] = max(f[i + 1][j - 1][q] , f[i + 1][j + 1][q]) + (s[i][j] - '0') ;
}
int res = -1 ;
for(int i = 1 ; i <= m ; i ++) res = max(res , f[1][i][0]) ;
printf("%d\n" , res) ;
if(res == -1) return 0 ;
int t = -1 , p = 0 ;
for(int i = 1 ; i <= m ; i ++)
if(f[1][i][0] == res)
{
t = i ;
break ;
}
for(int i = 1 ; i < n ; i ++)
{
int q = get(p - (s[i][t] - '0')) ;
if(f[i + 1][t - 1][q] + (s[i][t] - '0') == f[i][t][p]) path[i] = 1 , t = t - 1 ;
else path[i] = 0 , t = t + 1 ;
p = q ;
}
printf("%d\n" , t) ;
for(int i = n - 1 ; i ; i --)
if(!path[i])
printf("%c" , 'L') ;
else
printf("%c" , 'R') ;
}