应该是一道很经典的简单DP了,之前东师ACM新生赛也有这个题,+7学姐的数塔
这次听了yxc老师讲了一下DP的思路,用代码实现了一下
思路分析:
DP的话,应该是有状态表示和状态计算两个东西,下面的图片简单列举了一下DP的思路,红色字体代表本题的思路
AC代码:
#include <bits/stdc++.h>
#define ll long long
const int N = 520;
using namespace std;
int w[N][N],f[N][N];
// w 代表 原矩阵
// f 代表 状态表示
int main() {
int n;
cin >> n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++)
cin >> w[i][j];
// 初始化DP边界
for(int i = 1; i <= n; i++)
f[n][i] = w[n][i];
// 求所有 状态表示
for(int i = n-1; i > 0; i--)
for(int j = 1; j <= i; j++)
f[i][j] = max( f[i + 1][j] , f[i + 1][j + 1] ) + w[i][j];
// 根据分析的状态表示,f(1,1)即为所求结果
cout << f[1][1] << endl;
return 0;
}
优化一下AC代码,其实w二维数组完全没必要开,可以直接使用f二维数组进行代替
#include <bits/stdc++.h>
#define ll long long
const int N = 520;
using namespace std;
int f[N][N];
int main() {
int n;
cin >> n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++)
cin >> f[i][j];
// 求所有 状态表示
for(int i = n-1; i > 0; i--)
for(int j = 1; j <= i; j++)
f[i][j] += max( f[i + 1][j] , f[i + 1][j + 1] );
// 根据分析的状态表示,f(1,1)即为所求结果
cout << f[1][1] << endl;
return 0;
}
还有个小插曲,就是二维数组的输入,居然卡了半天没找出来是为啥,生气!!!
int n;
cin >> n;
for(int i = 0; i < n; i++)
for(int j = 0; j <= i; j++)
cin >> w[i][j];
for(int i = 0; i < n; i++) {
for(int j = 0; j <= i; j++)
printf("%d ",w[i][j]);
printf("\n");
}
printf("**** ****\n");
一定要注意二重循环!!!for(int j = 0; j <= i; j++)
这里面的j是<=i的!!!!