跑图类dp问题


一.跑图类dp问题的定义

对于数字三角形模型(跑一个金字塔求最值)所演变出来的一系列跑图求最值的模型,我统称为跑图类dp问题

二.经典案例(传纸条)

https://www.acwing.com/activity/content/problem/content/1286/1/

1.解法分析

本题可以看作是两个人同时从起点出发(原因稍微想一下就明白了),按照闫式分析法,dp[k][i1][i2]表示的含义是走k步,两个人分别走到第i1,i2行的时候dp的最大值,那么从当前状态dp[k][i1][i2]易得:上一个状态的集合dp[k-1] 有四个元素,分别是第一个人和第二个人从向右走和向下走到(i1,k-i1),(i2,k-i2),经过排列组合2X2共有四个元素

2.AC代码:

//这题直接套方格取数的模板即可就最后输出的时候要注意以下,出发点和终点会重合
#include<bits/stdc++.h>
using namespace std;
const int N=101; 
int dp[N][N][N];
int g[N][N];
int mx(int a,int b,int c,int d) 
{
    a=max(a,b);
    a=max(a,c);
    a=max(a,d);
    return a;
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>g[i][j];
        }
    }
    //循环这里可以直接i1和i2<=n即可,但是为了效率更高,我用了min.由于合法的dp值必然是从合法的dp值转移过来,所以不必担心i1,i2超过k的问题
    for(int k=1;k<=n+m;k++){
        for(int i1=1;i1<=n;i1++){
            for(int i2=1;i2<=n;i2++){
                if(i1==i2)
                    continue;
                else{
                    dp[k][i1][i2]=mx(dp[k-1][i1-1][i2-1],dp[k-1][i1-1][i2],dp[k-1][i1][i2-1],dp[k-1][i1][i2])+g[i1][k-i1]+g[i2][k-i2];
                }
            }
        }
    }
    //因为他们仅仅只在终点和起点会重合,且这两个点的g值为0,所以算到n+m-1步即可
    cout<<dp[n+m-1][n-1][n];
}

三.总结

关于跑图类的模型 其实只要分析清楚定好dp数组的含义,然后找好上一个点集合的元素再列式子就能轻易解决,大部分题目较为简单,但是要注意一下是求最大值还是最小值,数据源有无负数,以及初始化位置dp值的初始化问题


文章作者: 灿若星河
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 灿若星河 !
评论
  目录