• 方格取数(number) 题解(dp)


    题目链接

    题目大意

    给你n*m个方格,每个格子有对应的值

    你从(1,1)出发到(n,m)每次只能往下往上往右,走过的点则不能走

    求一条路线使得走过的路径的权值和最大

    题目思路

    如果只是简单的往下和往右走就是直接dp

    而如果是可以往上走,那么就要设置dp维度

    (dp[i][j][0]代表(i,j)从左转移下来)

    (dp[i][j][1]代表(i,j)从上转移下来)

    (dp[i][j][2]代表(i,j)从下转移下来)

    这个dp显然循环是要从先枚举列,再枚举行

    预处理第一列,求答案即可

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=1e3+5;
    int n,m;
    int a[maxn][maxn];
    ll dp[maxn][maxn][3];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
            }
        }
        memset(dp,-0x3f,sizeof(dp));
        dp[0][1][1]=0;
        for(int i=1;i<=n;i++){
            dp[i][1][1]=dp[i-1][1][1]+a[i][1];
        }
        for(int j=2;j<=m;j++){
            for(int i=1;i<=n;i++){
                dp[i][j][0]=max({dp[i][j-1][0],dp[i][j-1][1],dp[i][j-1][2]})+a[i][j];
            }
            for(int i=2;i<=n;i++){
                dp[i][j][1]=max({dp[i-1][j][0],dp[i-1][j][1]})+a[i][j];
            }
            for(int i=n-1;i>=1;i--){
                dp[i][j][2]=max({dp[i+1][j][2],dp[i+1][j][0]})+a[i][j];
            }
        }
        printf("%lld
    ",max(dp[n][m][1],dp[n][m][0]));
        return 0;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    C# 学习历程——接口
    C# 学习历程——类的封装,继承与多态
    C# 学习历程——C#基础
    C# 学习历程——Hello World
    python(14)---发邮件、写日志、操作redis数据库
    python(13)——内置函数
    python(12)---导入模块
    HTML操作之DOM操作
    HTML基础之CSS
    HTML基础之HTML标签
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/13956143.html
Copyright © 2020-2023  润新知