题意
给一个数n,输入一个n阶的数字三角形,开始从三角形顶端出发,每次向下走一步,只能走和他相邻的两个格子,每个格子有一个积分。问你最多能获得多少积分。
分析
入门级别的dp题,这里还是详细说下状态和转移吧。
首先dp[i][j]表示,从顶端到达(i,j)这个点的最大分数(要算上这个点的分值)。因为每次只能走下面相邻的两个,对于第一个数和最后一个数只能从上面一个走,所以直接加,中间的数取个最大值即可,具体看代码。
这里给的是Poj的代码,HDU给的输入形式是告诉了测试数量,所以提交的时候需要改改格式
代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int mp[355][355];
int dp[355][355];
int main()
{
int n;
while (cin >> n)
{
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++)
cin >> mp[i][j];
dp[1][1] = mp[1][1];
for (int i = 2; i <= n; i++)
for (int j = 1; j <= n; j++)
{
//如果是第一个就取上面一个值
if (j == 1) dp[i][j] = dp[i-1][j]+mp[i][j];
//如果是最后一个也是上面一个的最后一个值
else if (j == i) dp[i][j] = dp[i-1][j - 1] + mp[i][j];
//如果是中间的话就比较一下大小
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + mp[i][j];
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans = max(ans, dp[n][i]);
cout << ans << endl;
}
return 0;
}