【acwing】275. 传纸条**** (dp)

穿越隧道

用方格取数的代码(稍改动)。
大佬的证明。为啥方格取数可以用传纸条代码。

方法① 注释了if(j1…)这一判断条件,将i1和i2的遍历上限设为n(行数)
AC代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 10;
int f[N][N][N];
int n,r,c,v,m;
int w[N][N];
int main(){
    scanf("%d %d",&n,&m);
    for(int i = 1; i <= n; i++){
        for(int j =1; j <= m; j ++){
        scanf("%d",&w[i][j]);
        }
    }
    for(int k = 2; k <= m + n; k++){
        for(int i1 = 1; i1 <= n; i1++){//当i1小于等于k时,if(j1<=k..)时,也能过。
            for(int i2 = 1; i2 <= n; i2++){
                int j1 = k - i1, j2 = k - i2;
                int &x = f[k][i1][i2];
                int t = w[i1][j1];
                // if(j1 >= 1 && j1 <= k && j2 >= 1 && j2 <= k){
                    if(i1 != i2) t += w[i2][j2];
                    x = max(x,f[k - 1][i1-1][i2] + t);//相当于从1 1这个矩阵格子往上和左,以及左上,以及自身来进行选择。
                    x = max(x,f[k - 1][i1-1][i2-1] + t);
                    x = max(x,f[k - 1][i1][i2] + t);
                    x = max(x,f[k - 1][i1][i2 - 1] + t);
                // }
            }
        }
    }
    printf("%d\n",f[m + n][n][n]);
    return 0;
}

方法② 将k的上限设为m+n;i1和i2的上限设为n; j1和j2的上限设为m。(m为列数)
AC代码如下

#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 10;
int f[N][N][N];
int n,r,c,v,m;
int w[N][N];
int main(){
    scanf("%d %d",&n,&m);
    for(int i = 1; i <= n; i++){
        for(int j =1; j <= m; j ++){
        scanf("%d",&w[i][j]);
        }
    }
    for(int k = 2; k <= m + n; k++){
        for(int i1 = 1; i1 <= n; i1++){//当i1小于等于k时,if(j1<=k..)时,也能过。
            for(int i2 = 1; i2 <= n; i2++){
                int j1 = k - i1, j2 = k - i2;
                int &x = f[k][i1][i2];
                int t = w[i1][j1];
                if(j1 >= 1 && j1 <= m && j2 >= 1 && j2 <= m){
                    if(i1 != i2) t += w[i2][j2];
                    x = max(x,f[k - 1][i1-1][i2] + t);//相当于从1 1这个矩阵格子往上和左,以及左上,以及自身来进行选择。
                    x = max(x,f[k - 1][i1-1][i2-1] + t);
                    x = max(x,f[k - 1][i1][i2] + t);
                    x = max(x,f[k - 1][i1][i2 - 1] + t);
                }
            }
        }
    }
    printf("%d\n",f[m + n][n][n]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值