7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
典型的数塔问题。
三种解决方案:
1、递归。
2、DP
3、记忆化搜索
今天用动态规划解决这一入门题。
状态转移方程:
dp[x][y] = max(dp[x+1][y],dp[x+1][y+1]) + maps[x][y];
动态规划是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题[1]和最优子结构性质的问题,用时往往远少于朴素解法。
动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。 这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAX 105
int maps[MAX][MAX];
int dp[MAX][MAX];
int n;
void DP(int x, int y)
{
for(int i = n - 1; i >= 1; i--)
{
for(int j = 1; j <= i; j++)
{
dp[i][j] = maps[i][j] + max(dp[i+1][j], dp[i+1][j+1]);
}
}
}
int main()
{
freopen("in.txt","r",stdin);
int i, j;
cin >> n;
for(i = 1; i <= n; i++)
{
for(j = 1; j <= i; j++)
{
cin >> maps[i][j];
}
}
for(i = 1; i <= n; i++)
{
dp[n][i] = maps[n][i];
}
DP(1, 1);
cout << dp[1][1] << endl;
}