动态规划问题
1. 数字三角形的(递归程序)
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define num 101
using namespace std;
int d[num][num];int n;
int maxsum(int i,int j){
if(i==n)return d[i][j];
else return max(maxsum(i+1,j),maxsum(i+1,j+1))+d[i][j];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
cin>>d[i][j];
cout<<maxsum(1,1);
return 0;
}
输入如图的矩阵 答案为30 下图为maxsum的调用次数
这种算法复杂度为(2的n次方)
如果每算出一个MaxSum(r,j)就保存起来,下次用
到其值的时候直接取用,则可免去重复计算。
递归转成记忆化
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define num 101
using namespace std;
int d[num][num];int n;
int SumMax[num][num];//用来表示i,j到最底层的最大值
int maxsum(int i,int j){
if(SumMax[i][j]!=-1)return SumMax[i][j];//先判断,如果这个 有计算过就直接返回
if(i==n)return SumMax[i][j]=d[i][j];
else return SumMax[i][j]=max(maxsum(i+1,j),maxsum(i+1,j+1))+d[i][j];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++){
cin>>d[i][j];
SumMax[i][j]=-1;//也就是说这个坐标点没有计算过
}
cout<<maxsum(1,1);
return 0;
}
空间优化
没必要用二维maxSum数组存储每一个MaxSum(r,j),只要从底层一行行向上
递推,那么只要一维数组maxSum[100]即可,即只要存储一行的MaxSum值就
可以。
进一步考虑,连maxSum数组都可以不要,直接用D的
第n行替代maxSum即可。
节省空间,时间复杂度不变
递推+空间优化 C++代码
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int n,d[101][101];
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
cin>>d[i][j];
for(int i=n-1;i>=1;i--)
for(int j=1;j<=i;j++)
d[n][j]=max(d[n][j],d[n][j+1])+d[i][j];
cout<<d[n][1];
return 0;
}