CF41D

观察到 \(n,m,k\) 均不大,考虑 dp。

\(dp_{i,j,l}\) 表示走到 \((i,j)\) 得到 \(l\) 个豆子可不可能。由于 \(a_{i,j}\le 9\),并且每次移动都会向上移动一行,所以 \(l\le 9\times n\)

转移较为简单,无非从 \((i+1,j-1)\)\((i+1,j+1)\) 转移,类似数字三角形。

关于答案,就是在 \(1\le j\le m\) 的情况下找到满足下面条件的最大 \(l\)

  • \(dp_{1,j,l}=1\)

  • \(l\)\(\mod (k+1)\) 意义下为 \(0\)

暴力枚举即可。

现在考虑如何求出一组路径。

假设答案是在 \(dp_{1,j,l}\) 上找到的,那么 \(dp_{2,j-1,l-a_{1,j}}\)\(dp_{2,j+1,l-a_{1,j}}\) 一定有一个是合法的(不然怎么转移过来)。于是我们可以倒退路径,记录每次向哪走即可。

#include<bits/stdc++.h>
#define int long long

template<typename T>
void read(T &x){
	 int f=1;
	 char c=getchar();
	 x=0;
	 while(c<'0'||c>'9'){
		 if(c=='-') f=-1;
		 c=getchar();
	 }
	 while(c>='0'&&c<='9') x=x*10+(int)(c-'0'),c=getchar();
	 x*=f;
}

template<typename T,typename I>
void chkmin(T &a,I b){
	 a=std::min(a,b);
}

template<typename T,typename I>
void chkmax(T &a,T b){
	a=std::max(a,b);
}

const int inf=1e18+10,MOD1=998244353,MOD2=1e9+7;

const int maxn=110;

int a[maxn][maxn],dp[maxn][maxn][1100],move[maxn],tot=0;

signed main(){
	int n,m,k;
	std::cin>>n>>m>>k;
	k++;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++) {
			char c;
			std::cin>>c;
			a[i][j]=(int)(c-'0');
		}
	memset(dp,0,sizeof(dp));
	for(int j=1;j<=m;j++) dp[n][j][a[n][j]]=1;
	for(int i=n-1;i>=1;i--){
		for(int j=1;j<=m;j++){
			//dp[i+1][j-1]  dp[i+1][j+1]
			for(int l=0;l<=900;l++){
				if(dp[i+1][j-1][l]) dp[i][j][(l+a[i][j])]=1;
				if(dp[i+1][j+1][l]) dp[i][j][(l+a[i][j])]=1; 
			}
		}
	}
	int ans=-1,ansj=-1,cnt=0;
	for(int j=1;j<=m;j++)
		for(int l=0;l<=1000;l++){
			if(l%k!=0) continue;
			if(dp[1][j][l]){
				if(l>ans) ans=l,ansj=j;
			}
		}
	printf("%lld\n",ans);
	if(ans==-1) return 0;
	for(int i=1;i<n;i++){
		//去推下一行
		ans-=a[i][ansj];
		if(ansj-1>0&&dp[i+1][ansj-1][ans]) ansj--,move[++tot]=2;
		else ansj++,move[++tot]=1;
	} 
	printf("%lld\n",ansj);
	for(int i=tot;i>=1;i--) printf("%c",(move[i]==1?'L':'R'));
	return 0;
}
/*
-读入字符一定检查回车
- 能不能搜索?
-函数要有返回值!
-想好了再写!
*/
posted @ 2024-02-19 10:54  BYR_KKK  阅读(19)  评论(0)    收藏  举报