数塔取数问题

来源:互联网 发布:中兴软件有限责任公司 编辑:程序博客网 时间:2024/05/18 06:53

Some thoughts on the algorithm problems recently.
B: 数塔取数问题

一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值。

每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上。

5

8 4

3 6 9

7 2 9 5

例子中的最优方案是:5 + 8 + 6 + 9 = 28

Input

第1行:N,N为数塔的高度。(2 <= N <= 500)
第2 - N + 1行:每行包括1层数塔的数字,第2行1个数,第3行2个数……第k+1行k个数。数与数之间用空格分隔(0 <= A[i] <= 10^5) 。

Output

输出最大值

Input示例

4
5
8 4
3 6 9
7 2 9 5

Output示例

28

一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值。

每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上。

5

8 4

3 6 9

7 2 9 5

例子中的最优方案是:5 + 8 + 6 + 9 = 28

Input

第1行:N,N为数塔的高度。(2 <= N <= 500)
第2 - N + 1行:每行包括1层数塔的数字,第2行1个数,第3行2个数……第k+1行k个数。数与数之间用空格分隔(0 <= A[i] <= 10^5) 。

Output

输出最大值

Input示例

4
5
8 4
3 6 9
7 2 9 5

Output示例

28

关于这个问题。很明显的用动态规划。
首先,寻找到状态。
我们假设用一个二维数组tree[][]来存储这个三角形里的所有数字。(名字太奇怪不用理会)
然后,用一个dp[][]二位数组来存储状态。
dp[i][j]表示什么呢?
首先,假设从最上面的那个位置往下走,我们尝试动态规划。
那么dp[i][j]表示从tree[0][0]走到tree[i][j]的最大和。
那么最终求得的结果就是max(dp[n][j],0<=j<=n)。
然后尝试得到状态转移方程。
dp[i][j]可能由dp[i-1][j-1]或者dp[i-1][j]得到。

*****dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+tree[i][j];


然后就势如破竹啦。

include

include

define MAX_N 501

define ll long long

ll tree[MAX_N][MAX_N];
ll dp[MAX_N][MAX_N];
ll max(ll x,ll y)
{
return x>y?x:y;
}
void set()
{
scanf(“%d”,&N);
for( int i=1;i<=N;i++)
{
for(int j = 1;j<=i;j++)
{
scanf(“%lld”,&tree[i][j]);
}
}
}
void show_tree()
{
for(int i=1;i<=N;i++)
{
for(int j=1;j<=i;j++)
{
printf(“%lld “,tree[i][j]);
}
printf(“\n”);
}
}
ll solve()
{
for(int i=N;i>0;i–)
{
for(int j=1;j<=i;j++)
{
dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+tree[i][j];
}
}
return dp[1][1];
}
int main(void)
{
set();
//show_tree();
printf(“%lld\n”,solve());
}

原创粉丝点击