数字三角形(动态规划)poj1163

该博客介绍了如何使用动态规划解决数字三角形问题,找到从顶部到底部的最大路径和。博主详细分析了状态转移方程的由来,并探讨了记忆化搜索与递推两种方法,强调了边界处理的重要性。最后,提供了实现算法的典型代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数,从第一行的数开始,每次可以往左下和右下走一格,直到走到最下行,把沿途经过的数全部加起来,如何才能使这个和最大??

状态转移方程由来的分析

需要用抽象的方法思考问题:把当前的位置(i,j)看成一个状态,然后定义状态(i,j)的指标函数d(i,j)为从格子(i,j)出发时能得到的最大和(包括(i,j)本身的值)。在这个状态定义下,原问题的解为d(1,1).
从格子(i,j)出发有两种决策,往左下走或者往右下走,应选择d(i+1,j),d(i+1,j+1)中较大的那一个,即
d(i,j)=(i,j)+max{d(i+1,j),d(i+1,j+1)}

记忆化搜索与递推

!!注意边界处理:即i=n时

记忆化搜索

虽然不像递推法那样显示的指明了计算顺序,但可保证每个节点只访问一次,时间复杂度为o(n^2)
首先用“menset(d,-1,sizeof(d));”把d全部初始化为-1,然后编写递归函数

<php>
int solve(int i,int j)
{if(d[i][j]!=-1)  return d[i][j];
 return d[i][j]=a[i][j]+(i==n?0:max(solve(i+1,j),solve(i+1,j+1)));
 }

上述程序依然是递归的,但同时也把计算结果保存在数组d中。题目中说各个数都是非负的,只需把所有d初始化为-1,即可通过判断得知它是否已经被计算过。

递推计算

可以用递推法计算状态转移方程。递推的关键是边界和计算顺序。在多数情况下,地推的时间复杂度是状态总数每个状态的决策个数决策时间
时间复杂度同记忆化搜索

int i,j;
for(j=1;j<=n;j++
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值