题目链接:HDU 2084 数塔
dp。
数塔的形状决定了数塔中除了最后一行每一个节点都肯定有两个子节点,所以从底向上推比较简单。从上向下还需要判断当前节点有几个父节点,最后判断最下边一行哪一个最大。
递推和记忆化搜索都可以。
#include <iostream>
using namespace std;
const int MAX_N = 100 + 10;
int arr[MAX_N][MAX_N];
int dp[MAX_N][MAX_N];
int n,T;
int main()
{
cin >> T;
while(T--)
{
cin >> n;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= i;j++)
{
cin >> arr[i][j];
dp[i][j] = 0;
}
}
for(int i = n;i > 0;i--)
{
for(int j = i;j > 0;j--)
{
if(i == n)
dp[i][j] = arr[i][j];
else
dp[i][j] = max(dp[i + 1][j],dp[i + 1][j + 1]) + arr[i][j];
}
}
cout << dp[1][1] << endl;
}
return 0;
}
#include <iostream>
using namespace std;
const int MAX_N = 100 + 10;
int arr[MAX_N][MAX_N];
int dp[MAX_N][MAX_N];
int n,T;
int DP(int i,int j)
{
if(dp[i][j] != -1)
return dp[i][j];
return dp[i][j] = max(DP(i + 1,j),DP(i + 1,j + 1)) + arr[i][j];
}
int main()
{
cin >> T;
while(T--)
{
cin >> n;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= i;j++)
{
cin >> arr[i][j];
if(i == n)
dp[i][j] = arr[i][j];
else
dp[i][j] = -1;
}
}
cout << DP(1,1) << endl;
}
return 0;
}