1. 程式人生 > 其它 >1.1數字三角形模型

1.1數字三角形模型

1015.摘花生(簡單)

題目描述:

給定行數為\(R\),列數為\(C\)的矩形花生地,每次可以向東或向南走,到了過一株花生苗就能摘走該它上面所有的花生。問從\((1,1)\)走到\((R,C)\)最多可以摘多少花生。

思路:

看到題意不難想到是動態規劃。
由於題意裡說了只能向東(右)或向南(下)走,所以對於上個狀態到這個狀態有兩種決策:向上或向左
明白這點後,就可以直接使用\(y\)\(DP\)分析法:

得到狀態轉移方程:

\(f[i,j]=max(f[i-1,j],f[i,j-1])+w[i,j]\)

Code:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n, m;
int w[N][N];
int f[N][N];

int main()
{
    int T;
    scanf("%d", &T);
    while (T -- )
    {
        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 i = 1; i <= n; i ++ )
            for (int j = 1; j <= m; j ++ )
                f[i][j] = max(f[i - 1][j], f[i][j - 1]) + w[i][j];
        
        printf("%d\n", f[n][m]);
    }
    return 0;
}

1018.最低通行費(簡單)

題目描述:

有一個商人,在\(N×N\)的房間中\((1,1)\)處,每次可以向下或向右移動,到了每個位置都需要支付\(w[i,j]\)元,最多走\(2×N-1\)步,問走到\((N,N)\)最少花費是多少。

思路:

題意中最多走\(2×N-1\)步的意思就是不能走回頭路,明白這點後就跟\(1015\).摘花生差不多了。
由於題意裡說了只能向右或向下走,所以對於上個狀態到這個狀態有兩種決策:向左或向上
要注意的是邊界情況:

  1. 在第一行中,上一步只能是由\((x,y-1)\)轉移得到
  2. 在第一列中,上一步只能是由\((x-1,y)\)轉移得到

\(y\)\(DP\)

分析法,可以得到:
\(f[i,j]=min(f[i-1,j],f[i,j-1])+w[i,j]\)

Code:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;
const int INF = 0x3f3f3f3f;

int n;
int w[N][N];
int f[N][N];

int main()
{
    scanf("%d", &n);
    
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= n; j ++ )
            scanf("%d", &w[i][j]);
    // 初始化
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= n; j ++ )
            f[i][j] = INF;
    f[1][1] = w[1][1];
            
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= n; j ++ )
        {
            if (i > 1) f[i][j] = min(f[i][j], f[i - 1][j] + w[i][j]);  // 不在第一行
            if (j > 1) f[i][j] = min(f[i][j], f[i][j - 1] + w[i][j]);  // 不在第一列
        }
            
    printf("%d", f[n][n]);
    
    return 0;
}