大卫的密码

题目链接

题意:

给定nxm矩阵,从(s,1)出发到(t,m)。
每次可以向下或向右移动一格
到达最后一行后可以继续向下并到达第一行(环形)
求路径权值最大和

思路:

对于任意一个位置,显然由于环形条件存在,其可由左 + 上 +(下+上)转移

并且无法返回前一列。

因此按列进行dp

记dp[i][j]:到达(i,j)得到的路径权值最大和
发现只有第一列的dp值确定

其他列依赖于第一列

对于(i,j)(j>1)

需dp确定其下面权值和的最大值X,答案为X+上面的权值和
需dp确定其上面权值和的最大值Y,答案为Y

dp[i][j]=max(X,Y)

nt n,m,s,t;
int a[2005][2005];
int f[2005][2005];
void solve(){
   cin>>n>>m>>s>>t;
   rep(i,1,n){
    rep(j,1,m){
        cin>>a[i][j];
    }
   }
   memset(f,-inf,sizeof f);
   f[s][1]=a[s][1];
   rep(j,1,m){

    vector<int>pre(n+1);
    vector<int>suf(n+2);
    vector<int>mxpre(n+1,-inf);
    vector<int>mxsuf(n+2,-inf);
    
    rep(i,1,n)pre[i]=pre[i-1]+a[i][j];
    for(int i=n;i>=1;i--)suf[i]=suf[i+1]+a[i][j];

    for(int i=n;i>=1;i--)mxsuf[i]=max(mxsuf[i+1],f[i][j-1]+suf[i]);
    rep(i,1,n)mxpre[i]=max(mxpre[i-1]+a[i][j],f[i][j-1]+a[i][j]);

    if(j==1){
        for(int i=1;i<s;i++){
            f[i][j]=suf[s]+pre[i];
        }
        for(int i=s+1;i<=n;i++){
            f[i][j]=pre[i]-pre[s-1];
        }
    }else{
        for(int i=1;i<=n;i++){
            f[i][j]=max(mxsuf[i+1]+pre[i],mxpre[i]);
        }
    }
   }
   cout<<f[t][m]<<endl;
}
posted @ 2025-05-26 18:06  Marinaco  阅读(19)  评论(0)    收藏  举报
//雪花飘落效果