7-1 数字三角形 (30 分)

给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。

QQ截图20170929023616.jpg

输入格式:

输入有n+1行:

第 1 行是数字三角形的行数 n,1<=n<=100。

接下来 n行是数字三角形各行中的数字。所有数字在0..99 之间。

输出格式:

输出最大路径的值。

输入样例:

在这里给出一组输入。例如:

5 
7 
3 8 
8 1 0 
2 7 4 4
4 5 2 6 5 

结尾无空行

输出样例:

在这里给出相应的输出。例如:

30

少用指针创建二维数组,血的教训,一不小心写错,debug几十分钟

这道题目采用动态规划的解法,有两种思路:

第一种:自上而下的填表,优点是容易理解,但是需要处理领界问题

#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    //保存数据
    int** a=new int*[n];
    for(int i=0;i<n;i++)
    {
        a[i]=new int[i+1];
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            cin>>a[i][j];
        }
    }
    //创建表 
    int** b=new int*[n];
    for(int i=0;i<n;i++)
    {
        b[i]=new int[i+1];
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            b[i][j]=a[i][j];
        }
    }
    /*核心代码*/ 
    //临界问题,填充临界值 
    for(int i=1;i<n;i++) 
    {
    	b[i][0]+=b[i-1][0];
    	b[i][i]+=b[i-1][i-1];
	}
	//填表 
    for(int i=2;i<n;i++)
    {
        for(int j=1;j<i;j++)
        {
            b[i][j]+=max(b[i-1][j],b[i-1][j-1]);
        }
    }
    int max=b[n-1][0];
	for(int i=1;i<n;i++)
	{
		if(max<b[n-1][i])max=b[n-1][i];
	}
	 //填表后的表 
//    for(int i=0;i<n;i++)
//    {
//    	for(int j=0;j<=i;j++)
//    	{
//    		cout<<b[i][j]<<" ";
//		}
//		cout<<endl;
//	}
    cout<<max; 
    //delete二维数组 
    for(int i=0;i<n;i++)
    {
        delete []a[i];
    }
    delete []a;
    for(int i=0;i<n;i++)
    {
        delete []b[i];
    }
    delete []b;
}//自底向上和自顶向下两种思路 

第二种思路:自底向上,无需处理邻界问题,表头就是最大值

代码大致相似

#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    //保存数据
    int** a=new int*[n];
    for(int i=0;i<n;i++)
    {
        a[i]=new int[i+1];
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            cin>>a[i][j];
        }
    }
    //创建表 
    int** b=new int*[n];
    for(int i=0;i<n;i++)
    {
        b[i]=new int[i+1];
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            b[i][j]=a[i][j];
        }
    }
    /*核心代码*/
	//填表 
    for(int i=n-2;i>=0;i--)
    {
        for(int j=0;j<=i;j++)
        {
            b[i][j]+=max(b[i+1][j],b[i+1][j+1]);
        }
    }	
    cout<<b[0][0]; 
    //delete二维数组 
    for(int i=0;i<n;i++)
    {
        delete []a[i];
    }
    delete []a;
    for(int i=0;i<n;i++)
    {
        delete []b[i];
    }
    delete []b;
}//自底向上和自顶向下两种思路 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值