基本动态规划一开始都是接触这个的,从回溯法转移到动态规划,其实就是在中间过程多了一个保存之前的值不用重复计算。
例题网站:数字三角形
递归解法(主要是在return那里加多个dp【i】【j】保存当前状态):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[1010][1010];
int d[1010][1010];
int dp(int i, int j) {
if(d[i][j] >= 0) return d[i][j];
return d[i][j] = max(dp(i+1,j),dp(i+1,j+1))+a[i][j];
}
int main()
{
int n;
memset(d,-1,sizeof(d));
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++) {
scanf("%d",&a[i][j]);
}
}
for(int i = 1; i <= n; i++) d[n][i] = a[n][i];
printf("%d\n",dp(1,1));
return 0;
}
递推解法(同理,只是递归的话是从起始点开始,递推的话从后面开始):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[1010][1010];
int d[1010][1010];
int main()
{
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++) {
scanf("%d",&a[i][j]);
}
}
for(int i = n; i > 0; i--) {
for(int j = 1; j <= i; j++) {
if(i == n) d[i][j] = a[i][j];
d[i][j] = a[i][j]+max(d[i+1][j],d[i+1][j+1]);
}
}
printf("%d\n",d[1][1]);
return 0;
}