题意:
给出一个矩阵,现在可以选择最底下一行的某一列作为开始点,直到到达最上面的行位置。每个字有一个值。要求求出最大的分数值并且这个分数值要能整数k这个整数。
题解:
和以往的水题dp不同这题限制了要整出k,其实需要什么状态就取什么状态呗。dp[i][j][k]表示i行j列余数为k的最大分数值。那么就很容可以求出解了。计算时,多加枚举左右点的余数值。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<map>
using namespace std;
typedef long long lld;
const int oo=0x3f3f3f3f;
//const lld OO=1LL<<61;
//const lld MOD=1000000007;
#define eps 1e-6
#define maxn 105
int dp[maxn][maxn][12];
struct DP
{
int col,d;
}path[maxn][maxn][12];
char str[maxn];
int maze[maxn][maxn];
char road[maxn*2],cnt;
int main()
{
int n,m,k;
while(scanf("%d %d %d",&n,&m,&k)!=EOF)
{
k++;
for(int i=1;i<=n;i++)
{
scanf("%s",str+1);
for(int j=1;j<=m;j++)
maze[i][j]=str[j]-'0';
}
memset(dp,-1,sizeof dp);
memset(path,-1,sizeof path);
for(int i=1;i<=m;i++)
dp[n][i][maze[n][i]%k]=maze[n][i];
for(int i=n-1;i>=1;i--)
{
for(int j=1;j<=m;j++)
{
int now;
for(int l=0;l<=k;l++)
{
if(dp[i+1][j-1][l]==-1)continue;
now=(l+maze[i][j])%k;
if(dp[i][j][now]<dp[i+1][j-1][l]+maze[i][j])
{
dp[i][j][now]=dp[i+1][j-1][l]+maze[i][j];
path[i][j][now].col=j-1;
path[i][j][now].d=l;
}
}
for(int r=0;r<=k;r++)
{
if(dp[i+1][j+1][r]==-1)continue;
now=(r+maze[i][j])%k;
if(dp[i][j][now]<dp[i+1][j+1][r]+maze[i][j])
{
dp[i][j][now]=dp[i+1][j+1][r]+maze[i][j];
path[i][j][now].col=j+1;
path[i][j][now].d=r;
}
}
}
}
int col,d=0,ans=-1,row=1;
for(int i=1;i<=m;i++)
if(ans<dp[1][i][0])
{
ans=dp[1][i][0];
col=i;
}
printf("%d\n",ans);
if(ans==-1) continue;
cnt=0;
while(path[row][col][d].d!=-1)
{
int next_col=path[row][col][d].col;
int next_d=path[row][col][d].d;
if(col<next_col)
road[++cnt]='L';
else
road[++cnt]='R';
row++;
col=next_col;
d=next_d;
}
printf("%d\n",col);
for(int i=cnt;i>=1;i--)
printf("%c",road[i]);
puts("");
}
return 0;
}
/**
3 3 1
123
456
789
3 3 0
123
456
789
2 2 10
98
75
4 3 10
194
707
733
633
*/