摘花生

 

 首先,这是一道DP的题嗯嗯 ……

既然这道题一个测试点有多张地图,所以我就定义了一个三维数组map来存储每一张矩阵图。

与此同时,再开一个数组dp[105][105][105]来表示每张图上从左上角的起始点到每个点能摘到的最多的花生。

再然后,开一个c[105]数组,一个r[105]数组来存储每张图的边界。

最后再开一个指针i表示当前在研究第几个矩阵、指针j表示该个正在被研究的数组的行,指针h表示该个正在被研究的数组的列。

这样,main函数以前的定义部分就写好了。

#include<iostream>
#include<algorithm>
using namespace std;
int map[105][105][105];
int dp[105][105][105];
int T,i,j,h;
int c[105],r[105];

 main函数内,先输入矩阵的数量,然后开始第一个for循环枚举研究第一个矩阵。

#include<iostream>
#include<algorithm>
using namespace std;
int map[105][105][105];
int dp[105][105][105];
int T,i,j,h;
int c[105],r[105];
int main(){
    cin>>T;
    for(i=1;i<=T;i++){

    }

}

 在大循环内,首先我们要读入每一张矩阵的长和宽c[i]和r[i],然后读入这张地图。

接下来,要对dp数组进行初始化。

先初始化dp[i][1][1]为map[1][1][1],因为这个位置没有其它位置可以到达。

然后初始化第一行和第一列,其中第一行只能从左边过来,第一列只能从上边到来,所以

dp[i][j][1]=dp[i][j-1][1]+map[i][j][1];//初始化行
dp[i][1][h]=dp[i][1][h-1]+map[i][1][h];//初始化列

 这样我们就得到了进一步完善的代码:

#include<iostream>
#include<algorithm>
using namespace std;
int map[105][105][105];
int dp[105][105][105];
int T,i,j,h;
int c[105],r[105];
int main(){
    cin>>T;
    for(i=1;i<=T;i++){
    cin>>c[i]>>r[i];
    for(j=1;j<=c[i];j++){//j和h代表每一张map的行和列
        for(h=1;h<=r[i];h++){
          cin>>map[i][j][h];
            }
        }
        dp[i][j][h]=map[i][1][1];
        for(j=1;j<=c[i];j++){//初始化行 
            dp[i][j][1]=dp[i][j-1][1]+map[i][j][1];
        }
        for(h=1;h<=r[i];h++){
            dp[i][1][h]=dp[i][1][h-1]+map[i][1][h];
        }
    }
}

 最后就是最重要的DP部分!

首先,第一行和第一列已经初始化完成,所以要从第二行、第二列开始枚举。

 然后,我们要考虑让该点的dp值更大(摘更多的花生)应该从左边来还是从上面来(因为题目中说只能往下走或往右走)。这里需要使用一个max函数,我用了STL中的头文件<algorithm>。

我们算出了从那边过来该点的dp值更大,再加上在这个点能摘的花生数,就可以得出该点最多能摘几个花生。

这样就得出了状态转移方程。

dp[i][j][h]=max(dp[i][j-1][h],dp[i][j][h-1])+map[i][j][h];

这样,我们就又一次完善了我们的代码。(前面记得要加头文件)

 最后还需要输出!

这很简单,只需要输出每个矩阵最右下角的位置的数值即可(因为其它位置都还能再移动去摘花生)

这样,我们就得到了完整的代码。

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 int map[105][105][105];
 5 int dp[105][105][105];
 6 int T,i,j,h;
 7 int c[105],r[105];
 8 int main(){
 9     cin>>T;
10     for(i=1;i<=T;i++){
11     cin>>c[i]>>r[i];
12     for(j=1;j<=c[i];j++){//j和h代表每一张map的行和列
13         for(h=1;h<=r[i];h++){
14           cin>>map[i][j][h];
15             }
16         }
17         dp[i][j][h]=map[i][1][1];
18         for(j=1;j<=c[i];j++){//初始化行 
19             dp[i][j][1]=dp[i][j-1][1]+map[i][j][1];
20         }
21         for(h=1;h<=r[i];h++){
22             dp[i][1][h]=dp[i][1][h-1]+map[i][1][h];
23         }
24         for(j=2;j<=c[i];j++){
25             for(h=2;h<=r[i];h++){
26                 dp[i][j][h]=max(dp[i][j-1][h],dp[i][j][h-1])+map[i][j][h];
27             }
28         }
29         cout<<dp[i][c[i]][r[i]]<<endl;
30     }
31     return 0;
32 }

这就是关于本题的具体讲解(第一次发DP题的题解,害怕……)

原文地址:https://www.cnblogs.com/qianr/p/12938211.html