• 摘花生


     

     首先,这是一道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题的题解,害怕……)

  • 相关阅读:
    HTML 相关面试题
    h5简写时钟效果
    软件工程结对作业二
    软件工程结对作业一
    软件工程第三次作业
    软件工程第二次作业
    软件工程第一次作业
    软件工程第四次作业
    软件工程第三次作业
    2019软件工程第二次作业(VS2017中对C++的单元测试)
  • 原文地址:https://www.cnblogs.com/qianr/p/12938211.html
Copyright © 2020-2023  润新知