DP-线性DP-数字三角形模型(路径DP)

DP-线性DP-数字三角形模型(路径DP)_第1张图片

以上是acwing的题谱

数字三角形

大致的题意就是给出一个n行的序列,序列的第i行有i个元素(i=1,2,3,...,n),需要你求出沿着这个序列从顶端走到底端元素和最大的一条路线

解题

给三角形的每一行每一列标上号,以当前位于第i行第j列来表示状态,用来的方向进行状态转移。

dp思路如下:

DP-线性DP-数字三角形模型(路径DP)_第2张图片

1.变式1

1.1摘花生

https://www.acwing.com/problem/content/1017/

有点类似于bfs走迷宫的问题,思路和朴素版差不多。这里更复杂的是可能会出现不同的情况,比如说某些格子不能走、不能重复走这些问题。

#include
using namespace std;
const int N=110;
int T;
int dx[2]={-1,0},dy[2]={0,-1};
int m[N][N];
int f[N][N];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        int r,c;
        scanf("%d%d",&r,&c);
        for(int i=0;i<=r+1;i++)
            for(int j=0;j<=c+1;j++) f[i][j]=0;
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
            {
                scanf("%d",&m[i][j]);
            }
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
            {
                for(int k=0;k<2;k++)
                {
                    int cx=i+dx[k],cy=j+dy[k];
                    f[i][j]=max(f[cx][cy]+m[i][j],f[i][j]);
                }
            }
        printf("%d\n",f[r][c]);
    }
}

1.2方格取数

登录—专业IT笔试面试备考平台_牛客网

设有N*N的方格图(N ≤ 10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0。如下图所示(见样例):

DP-线性DP-数字三角形模型(路径DP)_第3张图片

某人从图的左上角的A 点出发,可以向下行走,也可以向右走,直到到达右下角的B点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。
此人从A点到B 点共走两次,试找出2条这样的路径,使得取得的数之和为最大。

解题

这里需要考虑两条路线的情况,我们的状态就变成了[i1][j1]和[i2][j2]这样一个四维的状态。

四维的状态还可以继续优化,我们分析可以发现,因为每当一个点被路过时,上面的东西就会被拿走,所以两个人先后走还是同时走时没有差别的。我们考虑同时走的情况,就存在有i1+j1=i2+j2这个性质,因此我们使k=i1+j1=i2+j2,用[k][i1][i2]这个三维的状态可以代替原来四维的状态。

每走一步我们需要判断当前1和2是否处于一个格子,避免出现同一件物品拿两次的情况。

DP-线性DP-数字三角形模型(路径DP)_第4张图片

#include
using namespace std;
const int N=15;
int f[N*2][N][N];
int g[N][N];
int main()
{
    int n;
    scanf("%d",&n);
    int a,b,c;
    while(cin>>a>>b>>c,a||b||c) g[a][b]=c;
    for(int k=2;k<=2*n;k++)
        for(int i1=1;i1<=n;i1++)
            for(int i2=1;i2<=n;i2++)
            {
                int j1=k-i1,j2=k-i2;
                if(j1>0&&j1<=n&&j2>0&&j2<=n)
                {
                    int w;
                    if(i1==i2) w=g[i1][j1];
                    else w=g[i1][j1]+g[i2][j2];
                    
                    f[k][i1][i2]=max(f[k-1][i1][i2]+w,f[k][i1][i2]);
                    f[k][i1][i2]=max(f[k-1][i1-1][i2-1]+w,f[k][i1][i2]);
                    f[k][i1][i2]=max(f[k][i1][i2],f[k-1][i1][i2-1]+w);
                    f[k][i1][i2]=max(f[k][i1][i2],f[k-1][i1-1][i2]+w); 
                }
                
            }
    printf("%d",f[2*n][n][n]);
}

变式2

2.1钉子和小球

题解可以参见之前写的这篇文章:DP-线性DP的一些题目-CSDN博客

你可能感兴趣的:(动态规划,算法,c++,动态规划)