Description
给出一个 n×m n × m 的矩阵 (aij) ( a i j ) ,初始可以在最后一行任意选取位置开始移动,每次只能移动到左上角或右上角,注意不能移动到矩阵区域外,直至移动到第一行,其得分为路径上元素之和,要求该得分要被 k+1 k + 1 整除,问最大得分以及对应的起始位置和路径
Input
第一行三个整数 n,m,k n , m , k ,之后输入一个 n n 个长度为的矩阵 (aij) ( a i j ) (2≤n,m≤100,0≤k≤10,0≤aij≤9) ( 2 ≤ n , m ≤ 100 , 0 ≤ k ≤ 10 , 0 ≤ a i j ≤ 9 )
Output
输出最大得分以及对应的起始位置和路径,无解则输出 −1 − 1
Sample Input
3 3 1
123
456
789
Sample Output
16
2
RL
Solution
令 k=k+1 k = k + 1 ,以 dp[i][j][l] d p [ i ] [ j ] [ l ] 表示从最后一行到第 i i 行第列,得分模 k k 余的所有路径中的最大得分,根据当前步往左上或右上走有转移:
dp[i−1][j−1][(l+ai−1,j−1)%k]=max(dp[i−1][j−1][(l+ai−1,j−1)%k],dp[i][j][l]+ai−1,j−1),j>1 d p [ i − 1 ] [ j − 1 ] [ ( l + a i − 1 , j − 1 ) % k ] = m a x ( d p [ i − 1 ] [ j − 1 ] [ ( l + a i − 1 , j − 1 ) % k ] , d p [ i ] [ j ] [ l ] + a i − 1 , j − 1 ) , j > 1
dp[i−1][j+1][(l+ai−1,j+1)%k]=max(dp[i−1][j+1][(l+ai−1,j+1)%k],dp[i][j][l]+ai−1,j+1),j<m d p [ i − 1 ] [ j + 1 ] [ ( l + a i − 1 , j + 1 ) % k ] = m a x ( d p [ i − 1 ] [ j + 1 ] [ ( l + a i − 1 , j + 1 ) % k ] , d p [ i ] [ j ] [ l ] + a i − 1 , j + 1 ) , j < m
max(dp[1][j][0],1≤j≤m) m a x ( d p [ 1 ] [ j ] [ 0 ] , 1 ≤ j ≤ m ) 即为答案
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=105;
int n,m,k,a[maxn][maxn],dp[maxn][maxn][11],pre[maxn][maxn][11],start;
char s[maxn],ans[maxn];
void output(int i,int j,int x)
{
if(i<n)
{
int flag=0;
for(int l=0;l<k;l++)
if((l+a[i][j])%k==x&&dp[i+1][j-1][l]!=-1&&dp[i+1][j-1][l]+a[i][j]==dp[i][j][x])
{
start=j-1;
output(i+1,j-1,l);
flag=1;
break;
}
if(flag)ans[n-i-1]='R';
else
{
for(int l=0;l<k;l++)
if((l+a[i][j])%k==x&&dp[i+1][j+1][l]!=-1&&dp[i+1][j+1][l]+a[i][j]==dp[i][j][x])
{
start=j+1;
output(i+1,j+1,l);
break;
}
ans[n-i-1]='L';
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
k++;
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=m;j++)a[i][j]=s[j]-'0';
}
memset(dp,-1,sizeof(dp));
for(int j=1;j<=m;j++)dp[n][j][a[n][j]%k]=a[n][j];
for(int i=n;i>1;i--)
for(int j=1;j<=m;j++)
for(int l=0;l<k;l++)
if(dp[i][j][l]!=-1)
{
if(j>1)dp[i-1][j-1][(l+a[i-1][j-1])%k]=max(dp[i-1][j-1][(l+a[i-1][j-1])%k],dp[i][j][l]+a[i-1][j-1]);
if(j<m)dp[i-1][j+1][(l+a[i-1][j+1])%k]=max(dp[i-1][j+1][(l+a[i-1][j+1])%k],dp[i][j][l]+a[i-1][j+1]);
}
int pos=1;
for(int j=1;j<=m;j++)
if(dp[1][j][0]>dp[1][pos][0])pos=j;
printf("%d\n",dp[1][pos][0]);
if(dp[1][pos][0]!=-1)
{
output(1,pos,0);
printf("%d\n",start);
ans[n]='\0';
printf("%s\n",ans);
}
return 0;
}