每日dpPawn CodeForces - 41D

在这里插入图片描述
可以跳左上或者跳右上,注意k范围比较小,所以开3维dp搞搞就ok啦。要注意的是%(k+1)而不是(k),记录路径套路(开个数组)一下,还有就是答案可能是零,所以ans初始化不要是0…

#include<bits/stdc++.h>

using namespace std;
const int maxn=1e6+10;


int dp[105][105][11];
int path[105][105][11];
int tu[105][105];

int main()
{
    int n,m,K;
    cin>>n>>m>>K;
    for(int i=1;i<=n;i++){
        getchar();
        for(int j=1;j<=m;j++){
            char ch;
            scanf("%c",&ch);
            tu[i][j]=ch-'0';
        }
    }
    memset(dp,-0x3f,sizeof dp);
    for(int i=1;i<=m;i++){
        dp[1][i][tu[1][i]%(K+1)]=tu[1][i];
        // cout<<1<<" "<<i<<" "<<tu[1][i]%(K+1)<<endl;
    }

    for(int i=2;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=0;k<=K;k++){
                if(dp[i-1][j-1][k]>=dp[i-1][j+1][k]&&dp[i-1][j-1][k]!=-0x3f3f3f3f){
                    if(dp[i][j][(tu[i][j]+k)%(K+1)]<=dp[i-1][j-1][k]+tu[i][j]){
                        dp[i][j][(tu[i][j]+k)%(K+1)]=max(dp[i][j][(tu[i][j]+k)%(K+1)],dp[i-1][j-1][k]+tu[i][j]);
                        path[i][j][(tu[i][j]+k)%(K+1)]=1;
                    }
                }else if(dp[i-1][j+1][k]!=-0x3f3f3f3f){
                    if(dp[i][j][(tu[i][j]+k)%(K+1)]<=dp[i-1][j+1][k]+tu[i][j]){
                        dp[i][j][(tu[i][j]+k)%(K+1)]=max(dp[i][j][(tu[i][j]+k)%(K+1)],dp[i-1][j+1][k]+tu[i][j]);
                        path[i][j][(tu[i][j]+k)%(K+1)]=2;
                    }
                    
                }
            }
        }
    }
    int idx=1;int maxv=-1;
    for(int i=1;i<=m;i++){
        if(maxv<dp[n][i][0]){
            idx=i;
            maxv=max(maxv,dp[n][i][0]);
        }
    }
    int x=n,y=idx;
    if(maxv==-1){
        cout<<-1<<endl;return 0;
    }
    cout<<maxv<<endl;
    cout<<idx<<endl;
    string ans;
    int kk=0;
    while(x>=1){
        // cout<<path[x][y][kk]<<endl;
        if(path[x][y][kk]==1){
            if(K)
            kk=(kk-tu[x][y]+(K+1)*100)%(K+1);
            x--,y--;
            ans+="L";
        }else if(path[x][y][kk]==2){
            if(K)
            kk=(kk-tu[x][y]+(K+1)*100)%(K+1);
            x--,y++;
            ans+="R";
        }else break;
        // cout<<x<<" "<<y<<" "<<kk<<endl;
    }
    cout<<ans<<endl;
    

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值