数字三角形
题目:
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
输入
第一个行一个正整数 rrr ,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
输出
单独的一行,包含那个可能得到的最大的和。
1.递归爆搜
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int a[1005][1005],dp[1005][1005]; int n; int max(int x,int y) { if(x>y) return x; else return y; } int dfs(int x,int y) { if(x==n) return a[x][y]; return max(dfs(x+1,y),dfs(x+1,y+1))+a[x][y]; } int main() { cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { cin>>a[i][j]; } } cout<<dfs(1,1)<<endl; return 0; }
2.递归回推
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int a[1005][1005],dp[1005][1005]; int n; int max(int x,int y) { if(x>y) return x; else return y; } int main() { cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { cin>>a[i][j]; } } for(int i=1;i<=n;i++) dp[n][i]=a[n][i]; for(int i=n-1;i>0;i--) { for(int j=1;j<=i;j++) { dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j]; } } cout<<dp[1][1]<<endl; return 0; }
3.记忆化搜索
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int a[1005][1005],dp[1005][1005]; int n; int max(int x,int y) { if(x>y) return x; else return y; } int dfs(int x,int y) { if(dp[x][y]>0) return dp[x][y]; if(x==n) return dp[x][y]=a[x][y]; return dp[x][y]=max(dfs(x+1,y),dfs(x+1,y+1))+a[x][y]; } int main() { cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { cin>>a[i][j]; } } cout<<dfs(1,1)<<endl; return 0; }