dp的正规解释是:动态规划(英语:Dynamic programming,DP)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
动态规划问题的三大性质(也是dp能用的三大条件):
最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
子问题重叠性质:子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
无后效性:将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。
————————————————
题目来源:蓝桥杯2020初赛 C++ C组I题
题目描述
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。
对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。
此外,向左下走的次数与向右下走的次数相差不能超过1。
输入格式
输入的第一行包含一个整数N (1 < N ≤ 100),表示三角形的行数。
下面的N 行给出数字三角形。数字三角形上的数都是0 至100 之间的整数。
输出格式
输出一个整数,表示答案。
输入样例
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例
27
————————————————
#include <stdio.h>
#include <string.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define N 100 + 1
int a[N][N];
int main()
{
int n;
scanf("%d", &n);
memset(a, 0, sizeof a);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++) {
scanf("%d", &a[i][j]);
a[i][j] += MAX(a[i - 1][j - 1], a[i - 1][j]);
}
if(n & 1)
printf("%d\n", a[n][n / 2 + 1]);
else
printf("%d\n", MAX(a[n][n / 2 + 1], a[n][n / 2]));
return 0;
}