个人认为,动态规划是每一个ACM练习人的槛,动态规划不一定是一个具体的算法,更像是一个思维,不断更新,不断判断,即使动态规划的优点也是它的磨人之处。今天就是介绍一个最简单的问题——数塔。
上图就是数塔,题目要求你去找一条路,让这条路的和最大。
先说一下思路:
首先,作为一个学过搜索的人,最先想到的就是把所有的可能都存进队列,直到最后一列。从原理上来说是可行,但是有点麻烦,而且容易超时。
所以,介绍一个新思路。
先设想一下,如果把图倒过来会怎么样?原来的思路是从上到下,现在从下到上试试。没错,你的路走窄了,前方的路变少了。用计算机思想介绍一下,设一个点(i,j),它的下一层是什么?是(i+1,j)或者(i+1,j+1),那么如果塔是倒的,(i+1,j)和(i+1,j+1)的下一层是(i,j)。如果要得到最大值,只需要选择两者之中的最大值进行加和。所以状态转移方程是*dp[i][j]=dp[i][j]+max(dp[i+1][j],dp[i+1][j+1])。
以上就是动态规划的思维,可以先尝尝试试,具体的内容以后再说。
加一段数塔的代码
///真的不难哈
#include <iostream>
using namespace std;
int arr[100][100];
int main()
{
int a,b,c,d,n,m;
cin >> n >> m;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cin >> arr[i][j];
}
}
for(int i=n-1;i>0;i--){
for(int j=1;j<=i;j++){
arr[i][j]=arr[i][j]+max(arr[i+1][j],arr[i+1][j+1]);
}
}
cout << arr[1][1];
return 0;
}