这篇文章上次修改于 529 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
本文共 920 个字,阅读时长 ≈ 3 分钟

AcWing 1015. 摘花生

题面:

Hello Kitty想摘点花生送给她喜欢的米老鼠。

她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。

地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。

Hello Kitty只能向东或向南走,不能向西或向北走。

问Hello Kitty最多能够摘到多少颗花生。

花生地


从左上角往右下角走,只能向下走或向右走,问最多能采到多少花生。很明显是一个数字三角形的模型,因为只有两种走法,状态转移方程为 $\text{f}[i][j]=\max(\text{f}[i-1][j],\text{f}[i][j-1])+a[i][j]$。

标准版代码:

#include<iostream>
using namespace std;
int a[120][120],f[120][120];
int t,r,c;
int main()
{
    cin>>t;
    while(t--){
        cin>>r>>c;
        for(int i=1;i<=r;++i){
            for(int j=1;j<=c;++j) cin>>a[i][j];
        }
        for(int i=1;i<=r;++i){
            for(int j=1;j<=c;++j)
                f[i][j]=max(f[i-1][j],f[i][j-1])+a[i][j];
        }
        cout<<f[r][c]<<endl;
    }
    return 0;
}

那为啥我说这个是标准版呢,因为$\text{f}[i][j]$最小会等于$\text{a}[i][j]$,然后就是看之前的值,所以我们可以直接用$\text{a}$数组来进行动态规划,这样可以省掉一部分空间。

优化版代码:

#include <iostream>
using namespace std;
int t,r,c;
int a[120][120];
int main()
{
    cin>>t;
    while(t--){
        cin>>r>>c;
        for(int i=1;i<=r;++i){
            for(int j=1;j<=c;++j){
                cin>>a[i][j];
                a[i][j]+=max(a[i-1][j],a[i][j-1]);
            }
        }
        cout<<a[r][c]<<endl;
    }
    return 0;
}