动态规划-入门篇

虽说以前学过,但好久没练基本上忘光了,那我就从入门篇开始刷起吧。

The Triangle
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 34125 Accepted: 20303

Description

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

(Figure 1)
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right. 

Input

Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.

Output

Your program is to write to standard output. The highest sum is written as an integer.

Sample Input

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

Sample Output

30

Source



题目要求:

输入一个n层的三角形,第i层有i个数,求从第1层到第n层的所有路线中,权值之和最大的路线。
规定:第i层的某个数只能连线走到第i+1层中与它位置相邻的两个数中的一个。


题目分析:我用map[i][j]代表三角形第i行j列的值,dp[i][j]代表从map[i][j]开始向下走的最大和,因此我们最终要求的最大和就是dp[0][0]。

代码:

#include<iostream>
using namespace std;
const int MAX=110;
int map[MAX][MAX];              //这个三角形
int dp[MAX][MAX];               


int main()
{
int n;
while(cin >> n)
{
for(int i=0;i<n;++i)
{
for(int j=0;j<=i;++j)
{
cin >> map[i][j];
}
}
for(int i=0;i<n;++i)
{
dp[n-1][i] = map[n-1][i];
}
for(int i=n-2;i>=0;i--)
{
for(int j=0;j<=i;++j)
{
dp[i][j] = map[i][j] + max(dp[i+1][j],dp[i+1][j+1]);
}
}
cout << dp[0][0] << endl;
}
return 0;
 } 


接下来,我们在对这段代码进行优化,我们不需要一个二维数组来保存每一个数字的最大和,首先我们用数组dp指向三角形的最后一行map[n-1],然后从最底层开始循环,逐步填充dp数组,最后最大和就是dp[0]

代码:

#include<iostream>
using namespace std;
const int MAX=110;
int map[MAX][MAX];
int *dp;


int main()
{
int n;
while(cin >> n)
{
for(int i=0;i<n;++i)
{
for(int j=0;j<=i;++j)
{
cin >> map[i][j];
}
}
dp = map[n-1];
for(int i=n-2;i>=0;i--)
{
for(int j=0;j<=i;++j)
{
dp[j]=max(dp[j],dp[j+1]) + map[i][j]; 
}
}
cout << dp[0] << endl;
}
return 0;
 } 

参考博客:http://blog.youkuaiyun.com/baidu_28312631/article/details/47418773

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值