luogu P1006 传纸条

题解

一道矩阵dp的升级版,难在来回两次怎么办?
想想可知来回其实就等价于走两次,怎样表示走两次呢?这又是个问题。
走一次的所有阶段和状态可以由二维数组解决,那么两次是不是可以用四维数组搞定呢。没错就是这么暴力。
定义 F [ i , j , k , q ] 为 第一走到[ i , j ] 第二走到[ k , q ] 时最大的积累值

那么就有状态转移方程
F [ i , j , k , q ] = max( F [ i-1 , j , k-1 , q ] ,F [ i -1, j , k , q-1 ] ,
                      F [ i , j-1 , k-1 , q ] ,F [ i , j-1 , k , q-1 ] ) + a[ i, j ] + a[ k , q]

当然还要解决一下 相遇问题,这个非常简单只要当位置重合时,将算得的累计值减去a[ i, j ] 或 a[ k , q]之一就好。

ps: 后续的代码用的时三维数组,这问题可优化成三维的,因为当以步数衡量时,知道x坐标的时候y坐标是显然的。


Code

// head files
using namespace std;

int n,m;
int cot[52][52];
int  f[150][52][52];
int max_of(int a,int b,int c,int d){
    return max(max(a,b),max(c,d));
}
int main(){

    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cin>>cot[i][j];
    }

    for(int k=1;k<= n+m-1;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if( k-i+1<1 || k-j+1 <1 ) continue;// out of range exclude

                f[k][i][j]=max_of(f[k-1][i][j],f[k-1][i-1][j-1],
                    f[k-1][i][j-1], f[k-1][i-1][j]
                ) + cot[i][k-i+1]+cot[j][k-j+1];

                if(i==j) // 相遇
                f[k][i][j] -= cot[i][k-i+1];
            }
        }
    }

    cout<<f[n+m-1][n][n]<<endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值