POJ 1163 动态规划

本文介绍使用动态规划算法解决三角形路径求和问题,通过递归与递推两种方式实现,旨在寻找从顶点到底部路径中数值之和的最大值。提供了C语言的AC代码示例。

本文系作者原创,转载请注明出处:https://blog.youkuaiyun.com/coder_what/article/details/83832160


题目链接:http://poj.org/problem?id=1163

题目算法:动态规划;可参考我的博客:https://blog.youkuaiyun.com/coder_what/article/details/83626100

递归边界:当遍历到最后一行时

状态转移方程:

Sum[i][j]=Max(MaxSum(i+1,j),MaxSum(i+1,j+1))+num[i][j]

法一(递归+储存):

递归的思路就是从上到下一直遍历,直到到达边界为止。

c语言的ac代码如下:

//Peking University ACM 1163
//Algorithm: LCS
#include<stdio.h>
#define max 101
int Max(int,int); //求最大值 
int MaxSum(int,int); //求最大的和
void Zero();//将Sum中的数全化为0 
int num[max][max]; //用来输入 
int Sum[max][max]; //用来储存算出来的和(用空间换时间,LCS的精华所在) 
int LineNumber; //行数 
int main()
{
	scanf("%d",&LineNumber);
	for(int i=0;i<LineNumber;i++)
		for(int j=0;j<=i;j++)  //key:用于输出三角形 
			scanf("%d",&num[i][j]);
	printf("%d",MaxSum(0,0));
	return 0;
}
void Zero()
{
	for(int i=0;i<LineNumber;i++)
		for(int j=0;j<=i;j++) 
			Sum[i][j]==0;
 } 
int Max(int a,int b)
{
	if(a>=b)	return a;
	return b;
}
int MaxSum(int i,int j)
{
	if(i==LineNumber-1)	return num[i][j];
	//边界:到达最下边,终止循环 ;-1是因为数组初始值为0 
	if(Sum[i][j]!=0) 	return Sum[i][j];
	//如果之前算过这个数,即存到了这个数组之中,则直接返回 
	else Sum[i][j]=Max(MaxSum(i+1,j),MaxSum(i+1,j+1))+num[i][j];
	return Sum[i][j];
}

法二(递推+储存):

递推的思路是从下往上走,第四行找到第五行最大的相加,第三行与第四行和第五行的和相加

C语言的ac代码如下:

//Peking University ACM 1163
//Algorithm: LCS
#include<stdio.h>
#define max 101
int Max(int,int); //求最大值 
int MaxSum(); //求最大的和
void Zero();//将Sum中的数全化为0 
int num[max][max]; //用来输入 
int Sum[max][max]; //用来储存算出来的和(用空间换时间,LCS的精华所在) 
int LineNumber; //行数 
int main()
{
	scanf("%d",&LineNumber);
	for(int i=0;i<LineNumber;i++)
		for(int j=0;j<=i;j++)  //key:用于输出三角形 
			scanf("%d",&num[i][j]);
	printf("%d",MaxSum());
	return 0;
}
void Zero()
{
	for(int i=0;i<LineNumber;i++)
		for(int j=0;j<=i;j++) 
			Sum[i][j]==0;
 } 
int Max(int a,int b)
{
	if(a>=b)	return a;
	return b;
}
int MaxSum()
{
	int i,j;
	for(i=0;i<LineNumber;i++)
		Sum[LineNumber][i]=num[LineNumber][i];  //将最后一行的值赋给Sum 
	for(i=LineNumber-1;i>=0;i--)//从下往上 (从到数第一行开始) 
		for(j=0;j<i+1;j++)
			Sum[i][j]=Max(Sum[i+1][j],Sum[i+1][j+1])+num[i][j];
	return Sum[0][0]; //返回最后一个值 
}

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值