一道经典的dp入门题

本文解析了一道经典的动态规划(DP)题目,通过构建一个数字三角形,探讨如何找到从顶点到底部路径上的最大和。文章详细介绍了DP的思维过程,状态转移方程的推导,以及使用C++实现的代码示例。

一道经典的DP题。。。感觉学DP都是从这题开始的。。。

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.
SampleInput
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
SampleOutput
30

题意就是输入一个n表示有n行,第i行有i个数,然后每次只能向下走或者右下走。从第一行到最后一行。求路径和最大是多少。。。

那么开始进入DP思维,找状态转移方程。每次向下或者向右下 移动的方向就说明了方程是
a[i] [j]=max( a [i+1] [j] ,a [i+1] [j+1] )+a[i] [j]。 这是从下往上更新的。。最后输出就是a[1][1]了。 当然也可以自上而下进行更新 不过最后的结果a[n] [j] 在最后一行,但具体在哪还需要遍历找最大一下。
下面代码展示

#include<iostream>
using namespace std;
int a[101][101];
int main()
{
    int n,i,j;
    cin>>n;
    for(i=1;i<=n;i++)
    for(j=1;j<=i;j++)
        cin>>a[i][j];
    for(i=n-1;i>=1;i--)
    {
        for(j=1;j<=i;j++)
            a[i][j]=max(a[i+1][j],a[i+1][j+1])+a[i][j];
    }
    cout<<a[1][1];
    return 0;
}

( cin是输入的意思 相当于c中的scanf函数,cout是输出 相当于c中的printf)。。

### 蓝桥杯经典概述 蓝桥杯大赛作为一项面向全国高校学生的编程竞赛活动,其目设计注重基础算法、数据结构以及实际应用能力的考察。以下是几类经典的蓝桥杯训练型及其特点: #### 1. 基础算法 这类目通常涉及简单的数学计算或逻辑推理,适合初学者入门。例如,“Fibonacci数列”的求解是一个常见的基础算法[^1]。 ```python def fibonacci(n): a, b = 0, 1 for _ in range(n): a, b = b, a + b return a print(fibonacci(10)) # 输出第10项斐波那契数 ``` #### 2. 字符串处理 字符串操作是蓝桥杯中的高频考点之一,可能包括子串查找、字符替换等内容。下面是一道关于统计特定字母出现次数的例子[^2]。 ```python def count_char(s, target): return s.count(target) result = count_char("bluebridge", 'e') print(result) # 输出'e'在字符串中出现的次数 ``` #### 3. 数据结构运用 利用栈、队列等基本数据结构解决问也是比赛重点。比如实现一个简易括号匹配验证程序可以锻炼选手对栈的理解[^3]。 ```python from collections import deque def is_valid_parentheses(s): stack = deque() mapping = {")": "(", "}": "{", "]": "["} for char in s: if char in mapping.values(): stack.append(char) elif char in mapping.keys(): if not stack or stack.pop() != mapping[char]: return False return not stack test_str = "(()){}[]" print(is_valid_parentheses(test_str)) # 判断括号序列是否合法 ``` #### 4. 动态规划与递推关系构建 对于稍有难度的问,则会测试参赛者动态规划的能力。像“最长公共子序列(LCS)”这样的问能够很好地体现这一点[^4]。 ```python def lcs_length(X, Y): m = len(X) n = len(Y) dp = [[0]*(n+1) for _ in range(m+1)] for i in range(1, m+1): for j in range(1, n+1): if X[i-1] == Y[j-1]: dp[i][j] = dp[i-1][j-1]+1 else: dp[i][j] = max(dp[i-1][j], dp[i][j-1]) return dp[m][n] sequence_x = "ABCBDAB" sequence_y = "BDCABA" length = lcs_length(sequence_x, sequence_y) print(length) # 找到两个字符串之间的LCS长度 ``` ### 总结 上述列举了几种典型的蓝桥杯练习方向,涵盖了从易至难的不同层次需求。通过这些实例的学习和实践可以帮助准备参加此类赛事的学生打下坚实的基础[^5]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我不会c语言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值