摘花生 (动态规划,线性dp)

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

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

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

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

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

摘花生 (动态规划,线性dp)_第1张图片

输入格式

第一行是一个整数T,代表一共有多少组数据。

接下来是T组数据。

每组数据的第一行是两个整数,分别代表花生苗的行数R和列数 C。

每组数据的接下来R行数据,从北向南依次描述每行花生苗的情况。每行数据有C个整数,按从西向东的顺序描述了该行每株花生苗上的花生数目M。

输出格式

对每组输入数据,输出一行,内容为Hello Kitty能摘到得最多的花生颗数。

数据范围

1≤T≤100,
1≤R,C≤100,
0≤M≤1000

输入样例:

2
2 2
1 1
3 4
2 3
2 3 4
1 6 5

输出样例:

8
16

思路:

        用f[i][j]表示i,j这个格子最多的花生有多少,

        状态转移:可以从上边或左边过来,所以取一个max,再加上本格子的花生

这样的话,空间复杂度就是O(n^2)的了,不过这个空间也可以开一个一维数组来dp

代码:

O(n^2)

#include
using namespace std;

const int N = 110;
int T, n, m;
int g[N][N];
int f[N][N];

int main()
{
	cin >> T;
	while (T--) {
		cin >> n >> m;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++) {
				cin >> g[i][j];
				f[i][j] = max(f[i - 1][j], f[i][j - 1]) + g[i][j];
			}
		cout << f[n][m] << endl;
	}
	return 0;
}

 O(n)

#include
#include
using namespace std;

const int N = 105;
int a[N][N], f[N], q, n, m;

int main()
{
    cin >> q;
    while(q--){
        cin >> n >> m;

        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                cin >> a[i][j];
            }
        }

        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                f[j] = max(f[j], f[j-1]) + a[i][j];
            }
        }
        cout << f[m] << endl;

        memset(f, 0, sizeof f);
    }
}

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