动态规划-入门篇

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

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.csdn.net/baidu_28312631/article/details/47418773

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态规划是一种用于解决一类具有重叠子问题和最优子结构性质问题的优化方法。它通过将问题分解为更小的子问题,并将子问题的解存储起来,以避免重复计算,从而提高算法的效率。 动态规划的基本步骤可以概括为三个:定义状态、设置状态转移方程和确定初始状态。 首先,我们需要定义问题的状态。状态是问题的不同阶段或步骤的某种表示。它可以是一个变量,也可以是一个数据结构。状态的定义需要根据问题的特性和要求进行设定。 接下来,我们需要设置状态转移方程。状态转移方程给出了问题从一个状态转移到另一个状态的规律。通过建立状态之间的联系,可以将问题分解为更小的子问题。这样,我们就可以通过已知子问题的解来求解更大的问题。 最后,我们需要确定初始状态。初始状态是问题最开始的状态。通过给出初始状态,可以递推得到后续的状态。 动态规划的核心思想是将问题分解为更小的子问题,并将子问题的解进行存储,以避免重复计算。这样做可以极大地减少计算量,提高算法的效率。 动态规划在解决一些经典问题中有着广泛的应用,比如最长递增子序列、0-1背包问题等。动态规划的理论和方法在计算机科学领域具有重要的意义,并且可以应用于其他领域,如经济学、生物学等。 总之,动态规划是一种重要的优化方法,可以有效地解决具有重叠子问题和最优子结构性质的问题。掌握动态规划的基本思想和方法对于解决复杂的问题具有重要的意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值